init_defaults();
$this->init_hooks();
}
private function init_defaults() {
$this->login_min_length = 3;
$this->login_max_length = 30;
$this->pass_min_length = 6;
$this->pass_max_length = 20;
$this->default = new stdClass();
$this->default->member = [
'user_login' => '',
'user_nicename' => '',
'user_email' => '',
'user_url' => '',
'user_registered' => '0000-00-00 00:00:00',
'user_activation_key' => '',
'display_name' => '',
'first_name' => '',
'last_name' => '',
'userid' => 0,
'title' => '',
'groupid' => 0,
'secondary_groupids' => [],
'groupids' => [],
'avatar' => '',
'cover' => '',
'posts' => 0,
'topics' => 0,
'questions' => 0,
'answers' => 0,
'comments' => 0,
'reactions_in' => [],
'reactions_out' => [],
'points' => 0,
'custom_points' => 0,
'online_time' => 0,
'timezone' => '',
'location' => '',
'signature' => '',
'occupation' => '',
'about' => '',
'status' => 'inactive',
'is_email_confirmed' => 0,
'is_mention_muted' => 0,
'fields' => [],
'group_name' => '',
'group_color' => '',
'profile_url' => '',
'dname' => '',
'rating' => [
'level' => 0,
'percent' => 0,
'color' => $this->rating( 0, 'color' ),
'title' => $this->rating( 0, 'title' ),
'badge' => $this->rating( 0, 'icon' ),
],
];
$this->default->action = [
'label' => 'Action Button',
'ico' => '',
'callback_for_can' => '',
'callback_for_get_url' => '',
'data' => [],
'confirm_msg' => '',
];
}
private function init_hooks() {
if( is_admin() ) add_action( 'wpforo_after_init', [ $this, 'init_list_table' ] );
add_action( 'delete_user_form', [ $this, 'show_delete_form' ], 10, 2 );
add_action( 'register_new_user', [ $this, 'after_register_new_user' ] );
add_action( 'after_password_reset', [ $this, 'after_password_reset' ] );
add_action( 'wp_login', [ $this, 'wp_login' ], 10, 2 );
add_action( 'set_current_user', [ $this, 'init_current_user' ] );
add_action( 'clean_user_cache', function( $userid ){ $this->reset( $userid ); } );
add_action( 'init', function() { if( ! WPF()->current_userid ) $this->init_current_user(); } );
add_action( 'set_logged_in_cookie', function( $logged_in_cookie ) {
$cookie = explode( '|', $logged_in_cookie );
WPF()->session_token = (string) wpfval( $cookie, 2 );
} );
add_action( 'wpforo_after_add_topic', [$this, 'after_add_topic'] );
add_action( 'wpforo_after_delete_topic', [$this, 'after_delete_topic'] );
add_action( 'wpforo_topic_status_update', [$this, 'after_topic_status_update'] );
add_action( 'wpforo_before_merge_topic', [$this, 'before_merge_topic'], 10, 3 );
add_action( 'wpforo_after_merge_topic', [$this, 'after_merge_topic'] );
add_action( 'wpforo_after_move_topic', [$this, 'after_move_topic'] );
add_action( 'wpforo_after_add_post', [$this, 'after_add_post'] );
add_action( 'wpforo_after_delete_post', [$this, 'after_delete_post'] );
add_action( 'wpforo_post_status_update', [$this, 'after_post_status_update'] );
add_action( 'wpforo_after_add_reaction', [$this, 'after_add_reaction'] );
add_action( 'wpforo_after_edit_reaction', [$this, 'after_edit_reaction'], 10, 2 );
add_action( 'wpforo_before_delete_reaction', [$this, 'before_delete_reaction'], 10, 2 );
add_action( 'wpforo_after_delete_reaction', [$this, 'after_delete_reaction'] );
add_action( 'wpforo_after_delete_user', [$this, 'after_delete_user'], 11, 2 );
add_action( 'wpforo_after_activate_user', [$this, 'after_activate_user'] );
}
public function init_list_table() {
if( wpfval( $_GET, 'page' ) === wpforo_prefix_slug( 'members' ) ) {
$this->list_table = new MembersListTable();
$this->list_table->prepare_items();
}
}
/**
* @param array $member
*
* @return array
*/
public function decode( $member ) {
$reaction_types = array_map( '__return_zero', array_flip( Reactions::get_type_list() ) );
$member = array_merge( $this->default->member, (array) $member );
$member['userid'] = wpforo_bigintval( $member['userid'] );
$member['first_name'] = trim( strip_tags( (string) $member['first_name'] ) );
$member['last_name'] = trim( strip_tags( (string) $member['last_name'] ) );
$member['groupid'] = intval( $member['groupid'] );
$member['secondary_groupids'] = array_map( 'intval', (array) ( is_scalar( $member['secondary_groupids'] ) ? explode( ',', $member['secondary_groupids'] ) : $member['secondary_groupids'] ) );
$member['secondary_groupids'] = array_diff( $member['secondary_groupids'], (array) $member['groupid'] );
$member['groupids'] = array_unique( array_filter( array_merge( (array) $member['groupid'], $member['secondary_groupids'] ) ) );
$member['avatar'] = preg_replace( '#^https?://#iu', '//', esc_url( (string) $member['avatar'] ) );
$member['cover'] = preg_replace( '#^https?://#iu', '//', esc_url( (string) $member['cover'] ) );
$member['topics'] = intval( $member['topics'] );
$member['posts'] = intval( $member['posts'] );
$member['questions'] = intval( $member['questions'] );
$member['answers'] = intval( $member['answers'] );
$member['comments'] = intval( $member['comments'] );
$member['reactions_in'] = array_map( 'intval', (array) ( wpforo_is_json( $member['reactions_in'] ) ? json_decode( $member['reactions_in'], true ) : $member['reactions_in'] ) );
$member['reactions_in']['__ALL__'] = 0;
foreach( $member['reactions_in'] as $r ) $member['reactions_in']['__ALL__'] += $r;
$member['reactions_in'] = array_merge( $reaction_types, $member['reactions_in'] );
$member['reactions_out'] = array_map( 'intval', (array) ( wpforo_is_json( $member['reactions_out'] ) ? json_decode( $member['reactions_out'], true ) : $member['reactions_out'] ) );
$member['reactions_out']['__ALL__'] = 0;
foreach( $member['reactions_out'] as $r ) $member['reactions_out']['__ALL__'] += $r;
$member['reactions_out'] = array_merge( $reaction_types, $member['reactions_out'] );
$member['custom_points'] = floatval( $member['custom_points'] );
$member['points'] = $member['custom_points'] ?: $this->calc_points( $member );
$member['rating'] = $this->calc_rating( $member['points'] );
$member['online_time'] = (int) ( $member['online_time'] && !is_numeric( $member['online_time'] ) ? strtotime( (string) $member['online_time'] . ' GMT' ) : $member['online_time'] );
$member['is_email_confirmed'] = (bool) (int) $member['is_email_confirmed'];
$member['is_mention_muted'] = (bool) (int) $member['is_mention_muted'];
$member['title'] = trim( strip_tags( (string) $member['title'] ) );
$member['profile_url'] = $this->get_profile_url( $member );
$member['dname'] = wpforo_user_dname( $member );
$member['fields'] = (array) ( wpforo_is_json( $member['fields'] ) ? json_decode( $member['fields'], true ) : $member['fields'] );
$member = wpforo_array_ordered_intersect_key( $member, $this->default->member );
if( ! $member['userid'] ) $member['timezone'] = '';
return array_merge( $member['fields'], $member );
}
/** @TODO use this function for member all insert|update queries
* @param $member
*
* @return array
*/
private function encode( $member ) {
$member = $this->decode( $member );
$member['secondary_groupids'] = implode( ',', $member['secondary_groupids'] );
$member['groupids'] = implode( ',', $member['groupids'] );
unset( $member['reactions_in']['__ALL__'], $member['reactions_out']['__ALL__'] );
$member['reactions_in'] = json_encode( $member['reactions_in'] );
$member['reactions_out'] = json_encode( $member['reactions_out'] );
$member['is_email_confirmed'] = intval( $member['is_email_confirmed'] );
$member['is_mention_muted'] = intval( $member['is_mention_muted'] );
$member['fields'] = json_encode( $member['fields'] );
return $member;
}
private function fix_action( $action ){
return array_merge( $this->default->action, $action );
}
private function _get_actions( $user ) {
$userid = wpforo_bigintval( $user['userid'] );
$actions = [
'edit' => [
'label' => wpforo_phrase( 'Edit Account Information', false ),
'ico' => '',
'callback_for_can' => function(){
return WPF()->perm->user_can_edit_account();
},
'callback_for_get_url' => function() use ( $user ){
return WPF()->member->get_profile_url( $user, 'account' );
}
],
'edit_dash' => [
'label' => wpforo_phrase( 'Edit User in Dashboard', false ),
'ico' => '',
'callback_for_can' => function(){
return current_user_can( 'administrator' );
},
'callback_for_get_url' => function() use ( $userid ) {
return admin_url( "user-edit.php?user_id=" . $userid );
}
],
'ban' => [
'label' => ( $user['status'] === 'banned' ? wpforo_phrase( 'Unban User', false ) : wpforo_phrase( 'Ban User', false ) ),
'ico' => '',
'callback_for_can' => function() use ( $userid ){
return $userid !== WPF()->current_userid && (WPF()->usergroup->can('bm') || wpforo_current_user_is( 'admin' ));
},
'callback_for_get_url' => function() use ( $userid ){
return '';
},
'data' => [
'currentstate' => (int) ($user['status'] === 'banned'),
'active_label' => wpforo_phrase( 'Unban User', false ),
'inactive_label' => wpforo_phrase( 'Ban User', false ),
],
'confirm_msg' => wpforo_phrase( 'Please confirm you want to do this action?', false ),
],
'delete' => [
'label' => wpforo_phrase( 'Delete Account', false ),
'ico' => '',
'callback_for_can' => function() use ($userid){
return (
( current_user_can( 'administrator' ) || WPF()->usergroup->can( 'dm' ) )
&& WPF()->perm->user_can_manage_user( WPF()->current_userid, $userid )
)
&& (
$userid !== WPF()->current_userid
|| ( !is_super_admin( $userid ) && apply_filters('wpforo_can_user_self_delete', true) )
);
},
'callback_for_get_url' => function() use ( $userid ){
return wp_nonce_url( trim( WPF()->member->get_profile_url( $userid ), '/' ) . '/?wpfaction=user_delete', 'user_delete', '_wpfnonce' );
},
'confirm_msg' => wpforo_phrase( 'Please confirm you want to do this action?', false ),
],
'delete_dash' => [
'label' => wpforo_phrase( 'Delete User in Dashboard', false ),
'ico' => '',
'callback_for_can' => function() use ($userid){
return (current_user_can('administrator')
&& WPF()->perm->user_can_manage_user( WPF()->current_userid, $userid )
&& $userid !== WPF()->current_userid);
},
'callback_for_get_url' => function() use ( $userid ){
return admin_url( wp_nonce_url( "users.php?action=delete&user=" . $userid, 'bulk-users' ) );
}
],
];
return array_map( [$this, 'fix_action'], apply_filters( 'wpforo_member_get_actions', $actions, $user ) );
}
public function get_action( $user, $key ) {
$actions = $this->_get_actions( $user );
return wpfval( $actions, $key );
}
public function get_actions( $user ) {
$actions = $this->_get_actions( $user );
return array_filter($actions, function( $action ) use ( $user ){
if( is_callable( $action['callback_for_can'] ) ) return call_user_func( $action['callback_for_can'] );
return true;
});
}
private function add_profile( $args ) {
if( !$userid = wpforo_bigintval( wpfval( $args, 'userid' ) ) ) return false;
$sql = "INSERT IGNORE INTO `" . WPF()->tables->profiles . "` (`userid`, `title`, `groupid`, `timezone`, `about`) VALUES ( %d, %s, %d, %s, %s )";
$sql = WPF()->db->prepare(
$sql,
$userid,
sanitize_text_field( wpfval( $args, 'title' ) ) ?: wpforo_setting( 'profiles', 'default_title' ),
(int) wpfval( $args, 'groupid' ) ?: WPF()->usergroup->default_groupid,
sanitize_text_field( wpfval( $args, 'timezone' ) ) ?: '',
stripslashes( wpforo_kses( trim( (string) wpfval( $args, 'about' ) ), 'user_description' ) ) ?: ''
);
$r = WPF()->db->query( $sql );
$this->reset( $userid );
return $r;
}
function create( $data ) {
if( ! wpforo_setting( 'authorization', 'user_register' ) ) {
WPF()->notice->add( 'User registration is disabled.', 'error' );
return false;
}
$user_fields = [];
if( ! empty( $data ) ) {
if( wpfval( $data, 'wpfreg' ) ) {
$user_fields = $data['wpfreg'];
} else {
$user_fields = $data;
}
}
//-- START -- copied from update code
//Define $user
$user = $user_fields;
//Define $userid
$userid = intval( wpfval( $user, 'userid' ) );
//Check custom fields and merge to $user array
if( wpfval( $data, 'data' ) && is_array( $data['data'] ) && ! empty( $data['data'] ) ) {
$custom_fields = $data['data'];
$user = array_merge( $custom_fields, $user );
}
//Check file uploading custom fields and merge to $user array
$file_data = isset( $_FILES['data']['name'] ) && $_FILES['data']['name'] && is_array( $_FILES['data']['name'] ) ? array_filter( $_FILES['data']['name'] ) : [];
$file_fields = WPF()->form->prepare_file_args( $file_data, $userid );
if( wpfval( $file_fields, 'fields' ) ) {
$user = array_merge( $file_fields['fields'], $user );
}
//Validate fields
$form_fields = $this->get_register_fields();
$result = WPF()->form->validate( $user, $form_fields );
if( wpfval( $result, 'error' ) ) {
if( wpforo_is_admin() && wpfval( $result['error'], 0 ) ) {
wp_die( $result['error'][0] );
} else {
WPF()->notice->add( $result['error'], 'error' );
return false;
}
}
//-- END -- copied from update code
$user_fields = apply_filters( 'wpforo_create_profile', $user_fields );
if( ! $user_fields ) {
WPF()->notice->add( 'Empty fields', 'error' );
return false;
} elseif( wpfval( $user_fields, 'error' ) ) {
WPF()->notice->add( sanitize_text_field( $user_fields['error'] ), 'error' );
return false;
}
$this->login_min_length = apply_filters( 'wpforo_login_min_length', $this->login_min_length );
$this->login_max_length = apply_filters( 'wpforo_login_max_length', $this->login_max_length );
$this->pass_min_length = apply_filters( 'wpforo_pass_min_length', $this->pass_min_length );
$this->pass_max_length = apply_filters( 'wpforo_pass_max_length', $this->pass_max_length );
if( ! wpforo_setting( 'authorization', 'user_register_email_confirm' ) && ! empty( $user_fields ) && is_array( $user_fields ) && ! empty( $user_fields['user_pass1'] ) ) {
remove_action( 'register_new_user', 'wp_send_new_user_notifications' );
remove_action( 'register_new_user', 'wpforo_send_new_user_notifications' );
add_action( 'register_new_user', function( $user_id ) {
wpforo_send_new_user_notifications( $user_id, 'admin' );
} );
do_action( 'wpforo_create_profile_before', $user_fields );
$errors = new WP_Error();
extract( $user_fields, EXTR_OVERWRITE );
$sanitized_user_login = sanitize_user( $user_login );
$user_email = apply_filters( 'user_registration_email', $user_email );
$user_pass1 = trim( substr( (string) $user_pass1, 0, 100 ) );
$user_pass2 = trim( substr( (string) $user_pass2, 0, 100 ) );
$illegal_user_logins = array_map( 'strtolower', (array) apply_filters( 'illegal_user_logins', [] ) );
if( $sanitized_user_login == '' ) {
$errors->add( 'empty_username', __( 'ERROR: Please enter a username.' ) );
WPF()->notice->add( 'Username is missed.', 'error' );
return false;
} elseif( ! validate_username( $user_login ) ) {
$errors->add( 'invalid_username', __( 'ERROR: This username is invalid because it uses illegal characters. Please enter a valid username.' ) );
WPF()->notice->add( 'Illegal character in username.', 'error' );
return false;
} elseif( strlen( (string) $user_login ) < $this->login_min_length || strlen( (string) $user_login ) > $this->login_max_length ) {
WPF()->notice->add( 'Username length must be between %d characters and %d characters.', 'error', [ $this->login_min_length, $this->login_max_length ] );
return false;
} elseif( username_exists( $sanitized_user_login ) ) {
$errors->add( 'username_exists', __( 'ERROR: This username is already registered. Please choose another one.' ) );
WPF()->notice->add( 'Username exists. Please insert another.', 'error' );
return false;
} elseif( in_array( strtolower( $sanitized_user_login ), $illegal_user_logins ) ) {
$errors->add( 'invalid_username', __( 'ERROR: Sorry, that username is not allowed.' ) );
WPF()->notice->add( 'ERROR: invalid_username. Sorry, that username is not allowed. Please insert another.', 'error' );
return false;
} elseif( $user_email == '' ) {
$errors->add( 'empty_email', __( 'ERROR: Please type your email address.' ) );
WPF()->notice->add( 'Insert your Email address.', 'error' );
return false;
} elseif( ! is_email( $user_email ) ) {
$errors->add( 'invalid_email', __( 'ERROR: The email address isn’t correct.' ) );
WPF()->notice->add( 'Invalid Email address', 'error' );
return false;
} elseif( email_exists( $user_email ) ) {
$errors->add( 'email_exists', __( 'ERROR: This email is already registered, please choose another one.' ) );
WPF()->notice->add( 'Email address exists. Please insert another.', 'error' );
return false;
} elseif( strlen( $user_pass1 ) < $this->pass_min_length || strlen( $user_pass1 ) > $this->pass_max_length ) {
WPF()->notice->add( 'Password length must be between %d characters and %d characters.', 'error', [ $this->pass_min_length, $this->pass_max_length ] );
return false;
} elseif( $user_pass1 != $user_pass2 ) {
WPF()->notice->add( 'Password mismatch.', 'error' );
return false;
} else {
do_action( 'register_post', $sanitized_user_login, $user_email, $errors );
$errors = apply_filters( 'registration_errors', $errors, $sanitized_user_login, $user_email );
if( $errors->get_error_code() ) {
$user_fields = [];
foreach( $errors->errors as $u_err ) $user_fields[] = $u_err[0];
WPF()->notice->add( $user_fields, 'error' );
return false;
}
$user_id = wp_create_user( $sanitized_user_login, $user_pass1, $user_email );
if( ! is_wp_error( $user_id ) && $user_id ) {
do_action( 'register_new_user', $user_id );
do_action( 'wpforo_create_user_after', $data );
wp_signon( [ 'user_login' => $sanitized_user_login, 'user_password' => $user_pass1 ] );
WPF()->notice->clear();
WPF()->notice->add( 'Success!', 'success' );
return $user_id;
}
}
} elseif( wpforo_setting( 'authorization', 'user_register_email_confirm' ) && ! empty( $user_fields['user_login'] ) && ! empty( $user_fields['user_email'] ) ) {
if( strlen( (string) $user_fields['user_login'] ) < $this->login_min_length || strlen( (string) $user_fields['user_login'] ) > $this->login_max_length ) {
WPF()->notice->add( 'Username length must be between %d characters and %d characters.', 'error', [ $this->login_min_length, $this->login_max_length ] );
return false;
}
if( is_multisite() && apply_filters( 'wpforo_mu_signup', false ) ) {
wpmu_signup_user( $user_fields['user_login'], $user_fields['user_email'] );
WPF()->notice->clear();
WPF()->notice->add( 'Success! Please check your mail for confirmation.', 'success' );
return true;
} else {
$user_id = register_new_user( $user_fields['user_login'], $user_fields['user_email'] );
}
if( ! is_wp_error( $user_id ) && $user_id ) {
do_action( 'wpforo_create_user_after', $data );
WPF()->notice->clear();
WPF()->notice->add( 'Success! Please check your mail for confirmation.', 'success' );
return $user_id;
}
}
if( ! empty( $user_id->errors ) ) {
$user_fields = [];
foreach( $user_id->errors as $u_err ) $user_fields[] = $u_err[0];
WPF()->notice->add( $user_fields, 'error' );
return false;
}
WPF()->notice->add( 'Registration Error', 'error' );
return false;
}
/**
* Updates user data
*
* @param array $data - User data as a simple array( field => value ) OR
* $data['member'] = array( field => value ) user and profile fields - Account form
* $data['wpfreg'] = array( field => value ) user and profile fields - Registration form
* $data['data'] = array( field => value ) user custom fields
*
* $data['member']['userid'] or $data['userid'] is required
*
* @param string|array $type User data update types (comma separated)
* $type = 'full' user fields, profile fields, custom fields
* $type = 'user' only user fields (wp_users table)
* $type = 'profile' only profile fields (wp_wpforo_profiles table)
* $type = 'custom_fields' only custom fields (wp_wpforo_profiles table > fields column)
* $type = 'profile, custom_fields'
*
* @param boolean $check_permissions Whether check the current editor permissions or not
*
* @return false|array wpForo User array
* @since 1.5.0
*
*/
public function update( $data, $type = 'full', $check_permissions = true ) {
$type = (array) $type;
switch( WPF()->current_object['template'] ) {
case 'register':
$form = 'wpfreg';
$form_fields = $this->get_register_fields();
break;
default:
$form = 'member';
$form_fields = $this->get_account_fields();
break;
}
if( ! $form_fields ) {
WPF()->notice->add( 'Form template not found', 'error' );
return false;
}
if( ! wpfkey( $data, $form ) ) {
if( in_array( 'custom_fields', $type ) && count( $type ) === 1 ) {
if( ! wpfval( $data, 'data' ) ) {
$data['data'] = $data;
if( wpfkey( $data, 'data', 'userid' ) ) unset( $data['data']['userid'] );
}
} else {
$data[ $form ] = $data;
}
}
if( wpfval( $data, 'userid' ) && ! wpfval( $data, $form, 'userid' ) ) $data[ $form ]['userid'] = $data['userid'];
if( wpfval( $data, $form, 'userid' ) ) {
$result_user = true;
$result_fields = true;
$result_profile = true;
$custom_fields = [];
//Define $user
$user = $data[ $form ];
//Define $userid
$userid = intval( $data[ $form ]['userid'] );
//Check profile editor permissions
if( $check_permissions ) WPF()->perm->can_edit_user( $userid );
//Check custom fields and merge to $user array
if( wpfkey( $data, 'data' ) && is_array( $data['data'] ) && ! empty( $data['data'] ) ) {
$custom_fields = $data['data'];
$user = array_merge( $custom_fields, $user );
}
//Check file uploading custom fields and merge to $user array
$file_data = isset( $_FILES['data']['name'] ) && $_FILES['data']['name'] && is_array( $_FILES['data']['name'] )
? array_filter( $_FILES['data']['name'], function( $key ){
if( trim((string) $key) && ($field = $this->get_field( $key )) ){
if( wpfval( $field, 'type' ) === 'file' ){
$mime_type = wpfval( $_FILES, 'data', 'type', $key );
$mime_types = wp_get_mime_types();
$allowed_mime_types = get_allowed_mime_types();
$name = wpfval( $_FILES, 'data', 'name', $key );
$ext = pathinfo( $name, PATHINFO_EXTENSION );
$size = intval( $field['fileSize'] );
$fileExtensions = array_filter( (array) (is_scalar( $field['fileExtensions'] ) ? explode( ',', trim( (string) $field['fileExtensions'] ) ) : $field['fileExtensions']) );
if( $fileExtensions ) {
if( in_array( $ext, $fileExtensions ) ) {
$extensions = explode( '|', array_search( $mime_type, $mime_types ) );
$e = in_array( $ext, $extensions );
} else {
$e = false;
}
} else {
$extensions = explode( '|', array_search( $mime_type, $allowed_mime_types ) );
$e = in_array( $ext, $extensions );
}
return ! empty( $e ) && wpfval( $_FILES, 'data', 'size', $key ) <= ( $size * 1024 * 1024 );
}
}
return false;
}, ARRAY_FILTER_USE_KEY )
: [];
$file_fields = WPF()->form->prepare_file_args( $file_data, $userid );
if( wpfval( $file_fields, 'fields' ) ) {
$user = array_merge( $file_fields['fields'], $user );
$custom_fields = ( ! empty( $custom_fields ) ) ? array_merge( $custom_fields, $file_fields['fields'] ) : $file_fields['fields'];
}
//Hooks
$user = apply_filters( 'wpforo_update_profile', $user );
do_action( 'wpforo_update_profile_before', $user );
if( wpfval( $user, 'error' ) || empty( $user ) ) {
$error_message = ( wpfval( $user, 'error_message' ) ) ? sanitize_text_field( $user['error_message'] ) : 'Unknown error in profile editing hook. Please disable all plugins and check it again.';
WPF()->notice->add( $error_message, 'error' );
return false;
}
//Validate avatar_url
if( wpfval($user, 'avatar_type') === 'remote' && wpfval( $user, 'avatar_url' ) ){
if( empty( getimagesize( $user['avatar_url'] ) ) ){
WPF()->notice->add( 'The avatar URL is not an image file.', 'error' );
return false;
}
}
//Validate fields
$result = WPF()->form->validate( $user, $form_fields );
if( wpfval( $result, 'error' ) ) {
if( is_admin() && wpfval( $result['error'], 0 ) ) {
wp_die( $result['error'][0] );
} else {
WPF()->notice->add( $result['error'], 'error' );
return false;
}
}
if( $gid = (int) wpfval( $user, 'groupid' ) ){
$err = '';
if( WPF()->current_object['template'] !== 'register' ) {
if( WPF()->form->owner() || ! wpforo_current_user_is( 'admin' ) ) {
$err = 'You have no permission to edit Usergroup field';
}
} else {
if( in_array( $gid, [ 1, 2, 4 ], true ) ) {
$err = 'Admin and Moderator Usergroups are not permitted';
} else {
$f = $this->get_field('groupid');
if( wpfval( $f, 'allowedGroupIds' ) ) {
$allowedGroupIds = wpforo_parse_args( $f['allowedGroupIds'] );
if( ! in_array( $gid, $allowedGroupIds, true ) ) {
$err = 'The selected Usergroup cannot be set';
}
} else {
$err = 'The selected Usergroup is not found in allowed list';
}
}
}
if( $err ){
unset( $user['groupid'] );
}
}
if( $sgids = array_filter( array_map( 'intval', (array) wpfval( $user, 'secondary_groupids' ) ) ) ){
$f = $this->get_field('secondary_groupids');
if( WPF()->current_object['template'] === 'register' || ( WPF()->form->owner() && $f['isEditable'] ) || ( ! WPF()->form->owner() && in_array( WPF()->current_user_groupid, (array) $f['canEdit'] ) ) || wpforo_current_user_is( 'admin' ) ) {
if( ! empty( $sgids ) ) {
$secondary_groupids = WPF()->usergroup->get_secondary_groupids();
foreach( $sgids as $sgid ) {
if( in_array( $sgid, [ 1, 2, 4 ], true ) ) {
$user['secondary_groupids'] = array_diff( $user['secondary_groupids'], [$sgid] );
}
if( ! in_array( $sgid, $secondary_groupids ) ) {
$user['secondary_groupids'] = array_diff( $user['secondary_groupids'], [$sgid] );
}
}
}
} else {
unset( $user['secondary_groupids'] );
}
}
//Sanitize fields
$user = WPF()->form->sanitize( $user, $form_fields );
//Update User Fields
if( ! empty( $user ) && ( in_array( 'full', $type ) || in_array( 'user', $type ) ) ) {
$result_user = $this->update_user_fields( $userid, $user, false );
}
//Update Profile Fields
if( ! empty( $user ) && ( in_array( 'full', $type ) || in_array( 'profile', $type ) ) ) {
$result_profile = $this->update_profile_fields( $userid, $user, false );
}
//Password field validation and update
$result_password = WPF()->form->validate_password( $user );
if( $result_password === false ) {
$result_password = true;
}
if( wpfval( $result_password, 'error' ) ) {
WPF()->notice->add( $result_password['error'], 'error' );
$result_password = false;
}
if( $result_password && wpfval( $user, 'old_pass' ) && wpfval( $user, 'user_pass1' ) ) {
$result_password = $this->change_password( $user['old_pass'], $user['user_pass1'], $userid );
}
//Upload avatar
if( wpfval( $user, 'avatar_type' ) === 'custom' ) {
$this->upload_avatar( $userid );
}
//Update Custom Fields
if( ! empty( $custom_fields ) && ( in_array( 'full', $type ) || in_array( 'custom_fields', $type ) ) ) {
$result_fields = $this->update_custom_fields( $userid, $custom_fields, false );
}
//Upload Files from Custom Fields
if( wpfval( $file_fields, 'files' ) ) {
$this->upload_files( $file_fields['files'] );
}
//Reset this user cache
$this->reset( $userid );
if( $result_user === false || $result_profile === false || $result_fields === false || $result_password === false ) {
return false;
} else {
WPF()->notice->add( 'Profile updated successfully', 'success' );
do_action( 'wpforo_update_profile_after', $user );
return $user;
}
}
return false;
}
public function update_user_fields( $userid, $data, $check_permissions = true ) {
$result_user = true;
if( $check_permissions ) WPF()->perm->can_edit_user( $userid );
//User Fields
if( wpfkey( $data, 'display_name' ) ) {
$user_fields['display_name'] = $data['display_name'];
$user_fields_types[] = '%s';
}
if( wpfkey( $data, 'user_email' ) ) {
$user_fields['user_email'] = $data['user_email'];
$user_fields_types[] = '%s';
}
if( wpfkey( $data, 'user_nicename' ) ) {
if( ! wpfval( $data, 'user_nicename' ) ) {
$user_info = get_userdata( $userid );
$data['user_nicename'] = sanitize_title( sanitize_user( $user_info->user_nicename, true ) );
}
$user_fields['user_nicename'] = $data['user_nicename'];
$user_fields_types[] = '%s';
update_user_meta( $userid, 'nickname', $data['user_nicename'] );
}
if( wpfkey( $data, 'first_name' ) ) {
update_user_meta( $userid, 'first_name', $data['first_name'] );
}
if( wpfkey( $data, 'last_name' ) ) {
update_user_meta( $userid, 'last_name', $data['last_name'] );
}
if( wpfkey( $data, 'user_url' ) ) {
$user_fields['user_url'] = $data['user_url'];
$user_fields_types[] = '%s';
}
if( ! empty( $user_fields ) && ! empty( $user_fields_types ) ) {
$result_user = WPF()->db->update( WPF()->db->users, $user_fields, [ 'ID' => $userid ], $user_fields_types, [ '%d' ] );
if( false === $result_user ) {
WPF()->notice->add( 'User data update failed', 'error' );
if( WPF()->db->last_error ) {
WPF()->notice->add( sanitize_text_field( WPF()->db->last_error ), 'error' );
}
} else {
clean_user_cache( $userid );
}
}
if( $result_user ) $this->reset( $userid );
return $result_user;
}
public function update_profile_field( $userid, $key, $value ) {
$r = false;
if( $key && ! is_null( $value ) ) {
$member = $this->encode( [ $key => $value ] );
if( wpfkey( $member, $key ) ){
$r = WPF()->db->update(
WPF()->tables->profiles,
[ $key => $value ],
[ 'userid' => $userid ],
[ wpforo_db_data_format( $member[ $key ] ) ],
[ '%d' ]
);
if( $r ) $this->reset( $userid );
}
}
return $r;
}
public function update_profile_fields( $userid, $data, $check_permissions = true ) {
$result_profile = true;
if( $check_permissions ) {
WPF()->perm->can_edit_user( $userid );
}
$member = $this->encode( $data );
$profile_fields = [];
$profile_fields_types = [];
//Profile Fields
if( wpfkey( $data, 'groupid' ) ) {
$profile_fields['groupid'] = $member['groupid'];
$profile_fields_types[] = '%d';
}
if( wpfkey( $data, 'title' ) ) {
$profile_fields['title'] = $member['title'];
$profile_fields_types[] = '%s';
}
if( wpfkey( $data, 'signature' ) ) {
$profile_fields['signature'] = $member['signature'];
$profile_fields_types[] = '%s';
}
if( wpfkey( $data, 'about' ) ) {
$profile_fields['about'] = $member['about'];
$profile_fields_types[] = '%s';
update_user_meta( $userid, 'description', $member['about'] );
}
if( wpfkey( $data, 'occupation' ) ) {
$profile_fields['occupation'] = $member['occupation'];
$profile_fields_types[] = '%s';
}
if( wpfkey( $data, 'location' ) ) {
$profile_fields['location'] = $member['location'];
$profile_fields_types[] = '%s';
}
if( wpfkey( $data, 'timezone' ) ) {
$profile_fields['timezone'] = $member['timezone'];
$profile_fields_types[] = '%s';
}
if( wpfkey( $data, 'avatar_type' ) && $data['avatar_type'] !== 'gravatar' && wpfval( $data, 'avatar_url' ) ) {
$profile_fields['avatar'] = esc_url( trim( (string) $data['avatar_url'] ) );
$profile_fields_types[] = '%s';
}
if( wpfkey( $data, 'avatar_type' ) && $data['avatar_type'] === 'gravatar' ) {
$profile_fields['avatar'] = '';
$profile_fields_types[] = '%s';
}
if( wpfkey( $data, 'cover' ) ) {
$profile_fields['cover'] = $member['cover'];
$profile_fields_types[] = '%s';
}
if( wpfkey( $data, 'secondary_groupids' ) ) {
$profile_fields['secondary_groupids'] = $member['secondary_groupids'];
$profile_fields_types[] = '%s';
}
if( wpfkey( $data, 'custom_points' ) ) {
$profile_fields['custom_points'] = $member['custom_points'];
$profile_fields_types[] = '%d';
}
if( wpfkey( $data, 'online_time' ) ) {
$profile_fields['online_time'] = $member['online_time'];
$profile_fields_types[] = '%d';
}
if( wpfkey( $data, 'status' ) ) {
$profile_fields['status'] = $member['status'];
$profile_fields_types[] = '%s';
}
if( wpfkey( $data, 'is_email_confirmed' ) ) {
$profile_fields['is_email_confirmed'] = $member['is_email_confirmed'];
$profile_fields_types[] = '%d';
}
if( wpfkey( $data, 'is_mention_muted' ) ) {
$profile_fields['is_mention_muted'] = $member['is_mention_muted'];
$profile_fields_types[] = '%d';
}
$profile_fields = apply_filters( 'wpforo_before_update_profile_fields', $profile_fields, $userid, $data, $check_permissions );
if( ! empty( $profile_fields ) ) {
$result_profile = WPF()->db->update( WPF()->tables->profiles, $profile_fields, [ 'userid' => intval( $userid ) ], $profile_fields_types, [ '%d' ] );
if( false === $result_profile ) {
WPF()->notice->add( 'User profile update failed', 'error' );
if( WPF()->db->last_error ) {
WPF()->notice->add( sanitize_text_field( WPF()->db->last_error ), 'error' );
}
}
}
do_action( 'wpforo_update_profile_fields', $userid, $data, $result_profile );
if( $result_profile ) $this->reset( $userid );
return $result_profile;
}
public function update_custom_field( $userid, $field_name, $field_value = null ) {
$result = false;
$fields = $this->get_custom_fields( $userid );
if( ! empty( $fields ) && $field_name && ! is_null( $field_value ) ) {
foreach( $fields as $name => $value ) {
if( $name == $field_name ) {
$fields[ $name ] = $field_value;
}
}
$custom_fields = array_filter( $fields );
$custom_fields = wpforo_unslashe( $custom_fields );
$custom_fields = wpforo_decode( $custom_fields );
$custom_fields = wpforo_encode( $custom_fields );
$fields_json = json_encode( $custom_fields, JSON_UNESCAPED_UNICODE );
$sql = "UPDATE `" . WPF()->tables->profiles . "` SET `fields` = %s WHERE `userid` = %d;";
$sql = WPF()->db->prepare( $sql, $fields_json, $userid );
$result = WPF()->db->query( $sql );
}
if( $result ) $this->reset( $userid );
return $result;
}
public function update_custom_fields( $userid, $custom_fields, $check_permissions = true ) {
$result_fields = true;
if( ! empty( $custom_fields ) ) {
if( $check_permissions ) {
WPF()->perm->can_edit_user( $userid );
}
$custom_fields = wpforo_unslashe( $custom_fields );
$custom_fields = wpforo_decode( $custom_fields );
$custom_fields = wpforo_encode( $custom_fields );
$data_old = $this->get_custom_fields( $userid );
if( $data_old && is_array( $data_old ) ) {
$custom_fields = wp_parse_args( $custom_fields, $data_old );
}
$fields_json = json_encode( $custom_fields, JSON_UNESCAPED_UNICODE );
$sql = "UPDATE `" . WPF()->tables->profiles . "` SET `fields` = %s WHERE `userid` = %d;";
$sql = WPF()->db->prepare( $sql, $fields_json, $userid );
$result_fields = WPF()->db->query( $sql );
if( false === $result_fields ) {
WPF()->notice->add( 'User custom field update failed', 'error' );
if( WPF()->db->last_error ) {
WPF()->notice->add( sanitize_text_field( WPF()->db->last_error ), 'error' );
}
}
}
if( $result_fields ) $this->reset( $userid );
return $result_fields;
}
public function upload_avatar( $userid = 0 ) {
$userid = intval( $userid );
$_FILES['avatar'] = wpforo_check_for_svg( $_FILES['avatar'] );
if( wpfval( WPF()->current_object, 'template' ) ) {
$template = WPF()->current_object['template'];
if( $template === 'account' ) {
if( ! WPF()->usergroup->can( 'upa' ) ) return false;
}
}
if( ! $user = $this->get_member( $userid ) ) return false;
$user_nicename = urldecode( (string) $user['user_nicename'] );
if( isset( $_FILES['avatar'] ) && ! empty( $_FILES['avatar'] ) && isset( $_FILES['avatar']['name'] ) && $_FILES['avatar']['name'] ) {
$name = sanitize_file_name( $_FILES['avatar']['name'] ); //myimg.png
$tmp_name = sanitize_text_field( $_FILES['avatar']['tmp_name'] ); //D:\wamp\tmp\php986B.tmp
$error = sanitize_text_field( $_FILES['avatar']['error'] ); //0
$size = intval( $_FILES['avatar']['size'] ); //6112
$upload_max_filesize = apply_filters( 'wpforo_avatar_upload_max_filesize', 2 * 1048576 );
if( $size > $upload_max_filesize ) {
WPF()->notice->clear();
WPF()->notice->add( 'Avatar image is too big maximum allowed size is %s', 'error', wpforo_print_size( $upload_max_filesize ) );
return false;
}
if( $error ) {
$error = wpforo_file_upload_error( $error );
WPF()->notice->clear();
WPF()->notice->add( $error, 'error' );
return false;
}
$avatar_dir = WPF()->folders['avatars']['dir'];
if( ! is_dir( $avatar_dir ) ) wp_mkdir_p( $avatar_dir );
$ext = pathinfo( $name, PATHINFO_EXTENSION );
if( ! wpforo_is_image( $ext ) ) {
WPF()->notice->clear();
WPF()->notice->add( 'Incorrect file format. Allowed formats: jpeg, jpg, png, gif.', 'error' );
return false;
}
$fnm = pathinfo( $user_nicename, PATHINFO_FILENAME );
$fnm = str_replace( ' ', '-', $fnm );
while( strpos( (string) $fnm, '--' ) !== false ) $fnm = str_replace( '--', '-', $fnm );
$fnm = preg_replace( "/[^-a-zA-Z0-9]/", "", (string) $fnm );
$fnm = trim( (string) $fnm, "-" );
$avatar_fname = $fnm . ( $fnm ? '_' : '' ) . $userid . "." . strtolower( (string) $ext );
$avatar_fname_orig = $fnm . ( $fnm ? '_' : '' ) . $userid . "." . $ext;
$avatar_path = $avatar_dir . DIRECTORY_SEPARATOR . $avatar_fname;
$avatar_path_orig = $avatar_dir . DIRECTORY_SEPARATOR . $avatar_fname_orig;
if( is_dir( $avatar_dir ) ) {
if( move_uploaded_file( $tmp_name, $avatar_path ) ) {
$image = wp_get_image_editor( $avatar_path );
if( ! is_wp_error( $image ) ) {
$image->resize( 150, 150, true );
$saved = $image->save( $avatar_path );
if( ! is_wp_error( $saved ) && $avatar_fname != $avatar_fname_orig ) {
if( defined( PHP_OS ) && strtoupper( substr( PHP_OS, 0, 3 ) ) !== 'WIN' ) unlink( $avatar_path_orig );
}
}
WPF()->db->update( WPF()->tables->profiles, [ 'avatar' => WPF()->folders['avatars']['url//'] . "/" . $avatar_fname ], [ 'userid' => intval( $userid ) ], [ '%s' ], [ '%d' ] );
$this->reset( $userid );
return true;
}
}
}
return false;
}
public function upload_files( $file_fields ) {
if( ! empty( $file_fields ) ) {
foreach( $file_fields as $field_name => $file_path ) {
if( wpfval( $_FILES, 'data', 'tmp_name', $field_name ) && ! move_uploaded_file( $_FILES['data']['tmp_name'][ $field_name ], $file_path ) ) {
WPF()->notice->add( 'Sorry, there was an error uploading attached file', 'error' );
}
}
}
}
public function get_custom_field( $userid, $field_name ) {
$field_value = '';
if( $userid ) {
$sql = WPF()->db->prepare( "SELECT `fields` FROM `" . WPF()->tables->profiles . "` WHERE userid = %d", $userid );
$fields = WPF()->db->get_var( $sql );
if( $fields ) {
$data = (array) json_decode( $fields, true );
if( ! empty( $data ) ) {
$data = wpforo_unslashe( $data );
if( wpfkey( $data, $field_name ) ) {
$field_value = $data[ $field_name ];
}
}
}
}
return $field_value;
}
public function get_custom_fields( $userid ) {
$data = [];
if( $userid ) {
$sql = WPF()->db->prepare( "SELECT `fields` FROM `" . WPF()->tables->profiles . "` WHERE userid = %d", $userid );
$fields = WPF()->db->get_var( $sql );
if( $fields ) {
$data = (array) json_decode( $fields, true );
}
$data = wpforo_unslashe( $data );
}
return $data;
}
public function change_password( $old_passw, $new_passw, $userid ) {
if( ! ($userid = wpforo_bigintval( $userid )) || ! ($user = $this->get_member( $userid )) ) {
WPF()->notice->clear();
WPF()->notice->add( 'Userid is wrong', 'error' );
return false;
}
$user['user_pass'] = ( $userdata = get_userdata( $userid ) ) ? $userdata->user_pass : '';
if( ! apply_filters( 'wpforo_change_password_validate', true, $old_passw, $new_passw, $user ) ) return false;
if( wp_check_password( $old_passw, $user['user_pass'], $userid ) ) {
wp_set_password( $new_passw, $userid );
if( ! wpforo_is_owner( $userid ) ) $this->inactive_to_active( $userid );
/**
* Login user after change password with new pass
*/
if( wpforo_is_owner( $userid ) ) {
wp_signon( [ 'user_login' => sanitize_user( $user['user_login'] ), 'user_password' => $new_passw ] );
}
WPF()->notice->add( 'Password successfully changed', 'success' );
return true;
}
WPF()->notice->clear();
WPF()->notice->add( 'Old password is wrong', 'error' );
return false;
}
public function get_status( $userid ) {
return WPF()->db->get_var(
WPF()->db->prepare(
"SELECT `status`
FROM " . WPF()->tables->profiles . "
WHERE `userid` = %d",
$userid
)
);
}
public function inactive_to_active( $userid, $user_login = '', $raw = false ) {
if( $this->get_status( $userid ) === 'inactive' ) {
if( $raw || !wpforo_setting( 'authorization', 'manually_approval' ) ){
$this->update_profile_fields( $userid, [ 'status' => 'active' ], false );
}else{
wp_safe_redirect( wpforo_url( '', 'cantlogin' ) );
exit();
}
}
}
public function synchronize_user( $userid, $roles_usergroups = [] ) {
$groupid = false;
if( ! $userid || ! ($user = get_userdata( $userid )) ) return false;
$user->roles = (array) $user->roles;
//Don't synchronize User Roles with Usergroups if the option is disabled
if( wpforo_setting( 'authorization', 'role_synch' ) ) {
if( ! $roles_usergroups ) $roles_usergroups = WPF()->usergroup->get_role_usergroup_relation();
if( ! empty( $roles_usergroups ) && ! empty( $user->roles ) ) {
foreach( $user->roles as $role ) {
if( isset( $roles_usergroups[ $role ] ) ) {
$groupid = $roles_usergroups[ $role ];
break;
}
}
}
}
if( ! $groupid ) {
if( is_super_admin( $userid ) || in_array( 'administrator', $user->roles ) ) {
$groupid = 1;
} elseif( in_array( 'editor', $user->roles ) ) {
$groupid = 2;
} elseif( in_array( 'customer', $user->roles ) ) {
$groupid = 5;
} else {
$groupid = WPF()->usergroup->default_groupid;
}
}
$insert_groupid = ( isset( $_POST['wpforo_usergroup'] ) && ! wpforo_setting( 'authorization', 'role_synch' ) ) ? intval( $_POST['wpforo_usergroup'] ) : $groupid;
$insert_timezone = ( isset( $_POST['wpforo_usertimezone'] ) ) ? sanitize_text_field( $_POST['wpforo_usertimezone'] ) : '';
$about = get_user_meta( $userid, 'description', true );
$return = $this->add_profile( [
'userid' => wpforo_bigintval( $userid ),
'groupid' => intval( $insert_groupid ),
'timezone' => sanitize_text_field( $insert_timezone ),
'about' => stripslashes( wpforo_kses( trim( (string) $about ), 'user_description' ) ),
] );
if( $return !== false && ( $secondary_groupids = wpfval( $_POST, 'wpforo_secondary_groupids' ) ) ) {
$this->set_secondary_groupids( $userid, $secondary_groupids );
}
return $return;
}
public function synchronize_users( $limit = null ) {
if( is_multisite() ) {
$sql = "SELECT `user_id` FROM `" . WPF()->db->usermeta . "` WHERE `meta_key` LIKE '" . WPF()->blog_prefix . "capabilities' AND `user_id` NOT IN( SELECT `userid` FROM `" . WPF()->tables->profiles . "` ) ORDER BY `user_id` ASC";
} else {
$sql = "SELECT `ID` as user_id FROM `" . WPF()->db->users . "` WHERE `ID` NOT IN( SELECT `userid` FROM `" . WPF()->tables->profiles . "` ) ORDER BY `ID` ASC";
}
if( ! is_null( $limit ) ) {
$sql .= " LIMIT " . intval( $limit );
}
$userids = WPF()->db->get_col( $sql );
if( ! empty( $userids ) ) {
$roles_usergroups = WPF()->usergroup->get_role_usergroup_relation();
foreach( $userids as $userid ) {
$this->synchronize_user( $userid, $roles_usergroups );
}
return false;
}
## -- START -- delete profiles where not participant on multisite blog
if( is_multisite() ) {
$sql = "DELETE FROM `" . WPF()->tables->profiles . "` WHERE `userid` NOT IN( SELECT `user_id` FROM `" . WPF()->db->usermeta . "` WHERE `meta_key` LIKE '" . WPF()->blog_prefix . "capabilities' )";
WPF()->db->query( $sql );
}
## -- END -- delete profiles where not participant on multisite blog
return true;
}
public function _get_member( $args ) {
if( ! $args ) return $this->get_guest();
$default = [
'userid' => null, // $userid
'user_nicename' => '' // $user_nicename
];
if( is_numeric( $args ) ) {
$args = [ 'userid' => $args ];
} elseif( ! is_array( $args ) ) {
$args = [ 'user_nicename' => $args ];
}
$args = wpforo_parse_args( $args, $default );
extract( $args );
$userid = wpforo_bigintval( $userid );
$user_meta_obj = true;
if( $user_nicename ) {
$user_obj = get_user_by( 'user_nicename', $user_nicename );
if( ! empty( $user_obj ) ) $userid = $user_obj->ID;
}
$member = get_user_meta( $userid, '_wpf_member_obj', true );
if( empty( $member ) ) {
$user_meta_obj = false;
$sql = "SELECT *,
ug.`name` AS group_name,
ug.`color` AS group_color,
fn.`meta_value` AS first_name,
ln.`meta_value` AS last_name
FROM `" . WPF()->db->users . "` u
INNER JOIN `" . WPF()->tables->profiles . "` p ON p.`userid` = u.`ID`
LEFT JOIN `" . WPF()->tables->usergroups . "` ug ON ug.`groupid` = p.`groupid`
LEFT JOIN `" . WPF()->db->usermeta . "` fn ON fn.`user_id` = u.`ID` AND fn.`meta_key` LIKE 'first_name'
LEFT JOIN `" . WPF()->db->usermeta . "` ln ON ln.`user_id` = u.`ID` AND ln.`meta_key` LIKE 'last_name'";
$wheres = [];
if( $userid ) $wheres[] = "`ID` = $userid";
if( $user_nicename ) $wheres[] = "`user_nicename` = '" . esc_sql( $user_nicename ) . "'";
if( ! empty( $wheres ) ) $sql .= " WHERE " . implode( " AND ", $wheres );
$member = WPF()->db->get_row( $sql, ARRAY_A );
}
if( ! empty( $member ) && ! $user_meta_obj ) update_user_meta( $userid, '_wpf_member_obj', $member );
if( $member ) $member = $this->decode( $member );
return $member;
}
public function get_member( $args ) {
return wpforo_ram_get( [$this, '_get_member'], $args );
}
public function get_members( $args = [], &$items_count = 0 ) {
$default = [
'include' => [], // array( 2, 10, 25 )
'exclude' => [], // array( 2, 10, 25 )
'status' => [ 'active', 'inactive', 'banned' ], // 'active', 'blocked', 'trashed', 'spamer'
'groupid' => null, // groupid
'online_time' => null, // groupid
'orderby' => 'userid', //
'order' => 'ASC', // ASC DESC
'offset' => 0, // OFFSET
'row_count' => null, // ROW COUNT
'groupids' => [], // array( 1, 2 )
];
$args = wpforo_parse_args( $args, $default );
extract( $args, EXTR_OVERWRITE );
$include = wpforo_parse_args( $include );
$exclude = wpforo_parse_args( $exclude );
$sql = "SELECT *,
ug.`name` AS group_name,
ug.`color` AS group_color,
fn.`meta_value` AS first_name,
ln.`meta_value` AS last_name
FROM `" . WPF()->db->users . "` u
INNER JOIN `" . WPF()->tables->profiles . "` p ON p.`userid` = u.`ID`
LEFT JOIN `" . WPF()->tables->usergroups . "` ug ON ug.`groupid` = p.`groupid`
LEFT JOIN `" . WPF()->db->usermeta . "` fn ON fn.`user_id` = u.`ID` AND fn.`meta_key` LIKE 'first_name'
LEFT JOIN `" . WPF()->db->usermeta . "` ln ON ln.`user_id` = u.`ID` AND fn.`meta_key` LIKE 'last_name'";
$wheres = [];
if( ! empty( $include ) ) $wheres[] = " u.`ID` IN(" . implode( ', ', array_map( 'intval', $include ) ) . ")";
if( ! empty( $exclude ) ) $wheres[] = " u.`ID` NOT IN(" . implode( ', ', array_map( 'intval', $exclude ) ) . ")";
if( ! empty( $status ) ) $wheres[] = " p.`status` IN('" . implode( "','", array_map( 'esc_sql', array_map( 'sanitize_text_field', $status ) ) ) . "')";
if( ! empty( $groupids ) ) $wheres[] = " (p.`groupid` IN(" . implode( ', ', array_map( 'intval', $groupids ) ) . ") OR CONCAT(',', p.`secondary_groupids`, ',') REGEXP ',(" . implode( '|', array_map( 'intval', $groupids ) ) . "),' )";
if( ! is_null( $groupid ) ) $wheres[] = " (p.`groupid` = " . intval( $groupid ) . " OR FIND_IN_SET(" . intval( $groupid ) . ", p.`secondary_groupids`) ) ";
if( ! is_null( $online_time ) ) $wheres[] = " p.`online_time` > " . intval( $online_time );
if( ! empty( $wheres ) ) $sql .= " WHERE " . implode( " AND ", $wheres );
$item_count_sql = preg_replace( '#SELECT.+?FROM#isu', 'SELECT count(*) FROM', $sql );
$item_count_sql = preg_replace( '#ORDER.+$#is', '', $item_count_sql );
if( $item_count_sql ) $items_count = WPF()->db->get_var( $item_count_sql );
if( $orderby === 'groupid' ) $orderby = 'p.`groupid`';
$sql .= esc_sql( " ORDER BY $orderby " . $order );
if( $row_count ) $sql .= esc_sql( " LIMIT $offset,$row_count" );
return array_map( [$this, 'decode'], WPF()->db->get_results( $sql, ARRAY_A ) );
}
public function search( $needle, $fields = [], $limit = null ) {
if( $needle ) {
$needle = sanitize_text_field( $needle );
if( empty( $fields ) ) {
$fields = [
'title',
'user_nicename',
'user_email',
'signature',
];
}
$sql = "SELECT `ID` FROM `" . WPF()->db->users . "` u
INNER JOIN `" . WPF()->tables->profiles . "` p ON p.`userid` = u.`ID`";
$wheres = [];
foreach( $fields as $field ) {
$f = $this->get_field( $field );
$field = sanitize_text_field( $field );
if( $f['isDefault'] ) {
$wheres[] = "`" . esc_sql( $field ) . "` LIKE '%" . esc_sql( $needle ) . "%'";
} else {
$needle = preg_quote( preg_quote( $needle ) );
if( in_array( $f['type'], [ 'text', 'search', 'textarea' ], true ) ) {
$wheres[] = "`fields` REGEXP '[{,]\"" . $field . "\":(\\\[[^\\\[]*)?\"[^\"]*" . esc_sql( $needle ) . "[^\"]*\"'";
} else {
$wheres[] = "`fields` REGEXP '[{,]\"" . $field . "\":(\\\[[^\\\[]*)?\"" . esc_sql( $needle ) . "\"'";
}
}
}
if( ! empty( $wheres ) ) {
$sql .= " WHERE " . implode( " OR ", $wheres );
if( $limit ) $sql .= " LIMIT " . intval( $limit );
return WPF()->db->get_col( $sql );
} else {
return [];
}
} else {
return [];
}
}
public function filter( $args, $limit = null ) {
if( $args && is_array( $args ) ) {
$sql = "SELECT `ID` FROM `" . WPF()->db->users . "` u
INNER JOIN `" . WPF()->tables->profiles . "` p ON p.`userid` = u.`ID`";
$wheres = [];
foreach( $args as $field => $needle ) {
$f = $this->get_field( $field );
$field = sanitize_text_field( $field );
if( $f['isDefault'] ) {
if( is_scalar( $needle ) ) {
$needle = sanitize_text_field( $needle );
$wheres[] = "`" . esc_sql( $field ) . "` LIKE '%" . esc_sql( $needle ) . "%'";
} elseif( is_array( $needle ) ) {
foreach( $needle as $n ) {
$n = sanitize_text_field( $n );
$wheres[] = "`" . esc_sql( $field ) . "` LIKE '%" . esc_sql( $n ) . "%'";
}
}
} else {
if( in_array( $f['type'], [ 'text', 'search', 'textarea' ], true ) ) {
if( is_scalar( $needle ) ) {
$needle = preg_quote( preg_quote( wpforo_encode( $needle ) ) );
$wheres[] = "`fields` REGEXP '[{,]\"" . $field . "\":(\\\[[^\\\[]*)?\"[^\"]*" . esc_sql( $needle ) . "[^\"]*\"'";
} elseif( is_array( $needle ) ) {
foreach( $needle as $n ) {
$n = preg_quote( preg_quote( wpforo_encode( $n ) ) );
$wheres[] = "`fields` REGEXP '[{,]\"" . $field . "\":(\\\[[^\\\[]*)?\"[^\"]*" . esc_sql( $n ) . "[^\"]*\"'";
}
}
} else {
if( is_scalar( $needle ) ) {
$needle = preg_quote( preg_quote( wpforo_encode( $needle ) ) );
$wheres[] = "`fields` REGEXP '[{,]\"" . $field . "\":(\\\[[^\\\[]*)?\"" . esc_sql( $needle ) . "\"'";
} elseif( is_array( $needle ) ) {
foreach( $needle as $n ) {
$n = preg_quote( preg_quote( wpforo_encode( $n ) ) );
$wheres[] = "`fields` REGEXP '[{,]\"" . $field . "\":(\\\[[^\\\[]*)?\"" . esc_sql( $n ) . "\"'";
}
}
}
}
}
if( $wheres ) {
$sql .= " WHERE " . implode( " AND ", $wheres );
if( $limit ) $sql .= " LIMIT " . intval( $limit );
return WPF()->db->get_col( $sql );
}
}
return [];
}
public function ban( $userid ) {
if( $userid == WPF()->current_userid ) {
WPF()->notice->add( 'You can\'t make yourself banned user', 'error' );
return false;
}
if( ! WPF()->usergroup->can( 'bm' ) || ! WPF()->perm->user_can_manage_user( WPF()->current_userid, intval( $userid ) ) ) {
WPF()->notice->add( 'Permission denied for this action', 'error' );
return false;
}
if( false !== WPF()->db->update( WPF()->tables->profiles, [ 'status' => 'banned' ], [ 'userid' => intval( $userid ) ], [ '%s' ], [ '%d' ] ) ) {
do_action( 'wpforo_after_ban_user', $userid );
$this->reset( $userid );
WPF()->notice->add( 'User successfully banned from wpforo', 'success' );
return true;
}
WPF()->notice->add( 'User ban action error', 'error' );
return false;
}
public function unban( $userid ) {
if( ! WPF()->usergroup->can( 'bm' ) || ! WPF()->perm->user_can_manage_user( WPF()->current_userid, intval( $userid ) ) ) {
WPF()->notice->add( 'Permission denied for this action', 'error' );
return false;
}
if( false !== WPF()->db->update( WPF()->tables->profiles, [ 'status' => 'active' ], [ 'userid' => intval( $userid ) ], [ '%s' ], [ '%d' ] ) ) {
do_action( 'wpforo_after_unban_user', $userid );
$this->reset( $userid );
WPF()->notice->add( 'User successfully unbanned from wpforo', 'success' );
return true;
}
WPF()->notice->add( 'User unban action error', 'error' );
return false;
}
public function activate( $userid ) {
if( false !== WPF()->db->update( WPF()->tables->profiles, [ 'status' => 'active' ], [ 'userid' => intval( $userid ) ], [ '%s' ], [ '%d' ] ) ) {
do_action( 'wpforo_after_activate_user', $userid );
$this->reset( $userid );
WPF()->notice->add( 'User successfully activated from wpforo', 'success' );
return true;
}
WPF()->notice->add( 'User activate action error', 'error' );
return false;
}
public function deactivate( $userid ) {
if( false !== WPF()->db->update( WPF()->tables->profiles, [ 'status' => 'inactive' ], [ 'userid' => intval( $userid ) ], [ '%s' ], [ '%d' ] ) ) {
do_action( 'wpforo_after_deactivate_user', $userid );
$this->reset( $userid );
WPF()->notice->add( 'User successfully deactivated from wpforo', 'success' );
return true;
}
WPF()->notice->add( 'User deactivate action error', 'error' );
return false;
}
/**
*
* @param int $userid
* @param int $reassign
*
* @return bool true | false if user successfully deleted
*/
public function delete( $userid, $reassign = null ) {
if( ! ( $userid = wpforo_bigintval( $userid ) ) ) return false;
do_action( 'wpforo_before_delete_user', $userid, $reassign );
if( false !== WPF()->db->delete( WPF()->tables->profiles, [ 'userid' => $userid ], [ '%d' ] ) ) {
do_action( 'wpforo_after_delete_user', $userid, $reassign );
WPF()->notice->add( 'User successfully deleted', 'success' );
return true;
}
WPF()->notice->add( 'User delete error', 'error' );
return false;
}
/**
* @deprecated since 2.1.6 version instead of this use $this->_get_avatar() method
*/
public function _avatar( $user, $attr = '', $size = 96 ) {
return $this->_get_avatar( $user, $size, $attr );
}
/**
* @deprecated since 2.1.6 version instead of this use $this->get_avatar() method
*/
public function avatar( $user, $attr = '', $size = 96 ) {
return wpforo_ram_get( [ $this, '_avatar' ], $user, $attr, $size );
}
public function _get_avatar( $user, $size = 96, $attr = '' ) {
return $this->get_avatar_html( $this->get_avatar_url( $user ), $user, $size, $attr );
}
public function get_avatar( $user, $size = 96, $attr = '' ) {
return wpforo_ram_get( [ $this, '_get_avatar' ], $user, $size, $attr );
}
public function _get_avatar_url( $user ) {
$cache = WPF()->cache->on( 'avatar' );
if ( is_scalar( $user ) ) {
$userid = wpforo_bigintval( $user );
$cache_avatar = apply_filters( 'wpforo_avatar_cache', true, $userid );
if ( $cache && $cache_avatar && $avatar_url = WPF()->cache->get_item( $userid, 'avatar' ) ) {
return str_replace( '#', '', (string) $avatar_url );
}
$avatar_url = (string) WPF()->db->get_var( WPF()->db->prepare( "SELECT `avatar` FROM `" . WPF()->tables->profiles . "` WHERE `userid` = %d", wpforo_bigintval( $userid ) ) );
} else {
$avatar_url = (string) wpfval( $user, 'avatar' );
$userid = wpforo_bigintval( wpfval( $user, 'userid' ) );
}
if ( $cache && $userid ) {
WPF()->cache->create( 'item', [ $userid => $avatar_url ?: '#' ], 'avatar' );
}
return apply_filters( 'wpforo_avatar_url', $avatar_url, $userid );
}
public function get_avatar_url( $user ) {
return wpforo_ram_get( [ $this, '_get_avatar_url' ], $user );
}
public function get_avatar_html( $url, $user = [], $size = 96, $attr = '' ) {
$size = intval( $size );
if( $url && wpforo_setting( 'profiles', 'custom_avatars' ) ) {
$url = apply_filters( 'wpforo_avatar_url', $url, $user );
$dname = ! is_scalar( $user ) ? wpforo_user_dname( $user ) : $this->get_member( $user )['dname'];
if( strpos( (string) $attr, 'alt=' ) === false ) $attr .= ' ' . sprintf('alt="%1$s"', esc_attr( $dname ));
if( strpos( (string) $attr, 'title=' ) === false ) $attr .= ' ' . sprintf('title="%1$s"', esc_attr( $dname ));
if( strpos( (string) $attr, 'height=' ) === false ) $attr .= ' ' . sprintf('height="%1$d"', $size);
if( strpos( (string) $attr, 'width=' ) === false ) $attr .= ' ' . sprintf('width="%1$d"', $size);
$img = '';
} else {
$userid = is_scalar( $user ) ? wpforo_bigintval( $user ) : (wpforo_bigintval( wpfval( $user, 'userid' ) ) ?: (string) wpfval( $user, 'user_email' ));
$img = get_avatar( $userid, $size );
if( $attr ) $img = str_replace( '
get_member( intval( basename( (string) $arg ) ) ) : $this->_get_member( intval( basename( (string) $arg ) ) ) ) ?: [ 'user_nicename' => basename( (string) $arg ) ] : $arg;
if( wpfkey( $user, 'userid' ) && wpfkey( $user, 'user_nicename' ) ){
$user_slug = ( wpforo_setting( 'profiles', 'url_structure' ) === 'id' ? $user['userid'] : $user['user_nicename'] );
if( $template === 'profile' ){
$profile_url = wpforo_url( $user_slug, 'member' );
}else{
$template_slug = wpforo_settings_get_slug( $template );
$profile_url = wpforo_url( "$user_slug/$template_slug", 'member' );
}
}else{
$profile_url = wpforo_home_url();
}
return apply_filters( 'wpforo_member_profile_url', $profile_url, $user, $template );
}
/**
* @param float $points
*
* @return array
*/
public function calc_rating( $points ) {
$rating = $this->default->member['rating'];
$rating['level'] = $this->rating_level( floatval( $points ), false );
$rating['percent'] = $rating['level'] * 10;
$rating['title'] = $this->rating( $rating['level'], 'title' );
$rating['color'] = $this->rating( $rating['level'], 'color' );
$rating['badge'] = $this->rating( $rating['level'], 'icon' );
return $rating;
}
/**
* @param $member
*
* @return float
*/
private function calc_points( $member ) {
$topic_points = intval( $member['topics'] ) * wpforo_setting( 'rating', 'topic_points' );
$post_points = intval( $member['posts'] ) * wpforo_setting( 'rating', 'post_points' );
$like_points = intval( wpfval( $member, 'reactions_in', 'up') ) * wpforo_setting( 'rating', 'like_points' );
$dislike_points = intval( wpfval( $member, 'reactions_in', 'down') ) * wpforo_setting( 'rating', 'dislike_points' );
$topic_points = (float) apply_filters( 'wpforo_member_get_points_topic_points', $topic_points, $member );
$post_points = (float) apply_filters( 'wpforo_member_get_points_post_points', $post_points, $member );
$like_points = (float) apply_filters( 'wpforo_member_get_points_like_points', $like_points, $member );
$dislike_points = (float) apply_filters( 'wpforo_member_get_points_dislike_points', $dislike_points, $member );
return $topic_points + $post_points + $like_points + $dislike_points;
}
public function get_count( $args = [] ) {
$sql = "SELECT SQL_NO_CACHE COUNT(*) FROM `" . WPF()->tables->profiles . "` p
INNER JOIN `" . WPF()->db->users . "` u ON u.`ID` = p.`userid` WHERE p.`status` NOT LIKE 'trashed'";
if( $args ) {
$wheres = [];
foreach( $args as $key => $value ) {
if( is_array( $value ) ) {
$wheres[] = "$key IN('" . implode( "','", array_map( 'esc_sql', $value ) ) . "')";
} else {
$wheres[] = "$key = '" . esc_sql( $value ) . "'";
}
}
if( $wheres ) $sql .= " AND " . implode( ' AND ', $wheres );
}
return (int) WPF()->db->get_var( $sql );
}
public function _is_online( $userid, $duration = null ) {
if( ! $duration ) $duration = wpforo_setting( 'profiles', 'online_status_timeout' );
$sql = "SELECT `online_time` FROM `" . WPF()->tables->profiles . "` WHERE `userid` = %d";
$sql = WPF()->db->prepare( $sql, $userid );
$online_time = intval( WPF()->db->get_var( $sql ) );
$current_time = time();
return ( $current_time - $online_time ) < $duration;
}
public function is_online( $userid, $duration = null ) {
return wpforo_ram_get( [ $this, '_is_online' ], $userid, $duration );
}
public function show_online_indicator( $userid, $ico = true ) {
if( $this->is_online( $userid ) ) : ?>
ram_cache->exists( $key ) ) return WPF()->ram_cache->get( $key );
$sql = "SELECT COUNT(DISTINCT `userid`, `ip`) AS total FROM `" . WPF()->tables->visits . "` WHERE `time` > %d";
$var = (int) WPF()->db->get_var( WPF()->db->prepare( $sql, $online_timeframe ) );
if( ! $var ) {
$sql = "SELECT COUNT(*) FROM `" . WPF()->tables->profiles . "` WHERE `online_time` > %d";
$var = (int) WPF()->db->get_var( WPF()->db->prepare( $sql, $online_timeframe ) );
}
WPF()->ram_cache->set( $key, $var );
return $var;
}
public function get_online_members( $count = 1, $groupids = [], $duration = null ) {
if( ! $duration ) $duration = wpforo_setting( 'profiles', 'online_status_timeout' );
$current_time = time();
$online_timeframe = $current_time - $duration;
$groupids = array_filter( wpforo_parse_args( $groupids ) );
$args = [
'groupids' => $groupids,
'online_time' => $online_timeframe, // $current_time - $duration
'orderby' => 'userid', // forumid, order, parentid
'row_count' => $count,
'order' => 'ASC', // ASC DESC
];
return $this->get_members( $args );
}
public function levels() {
$max_rating_levels = (int) apply_filters('wpforo_max_rating_levels', 10);
return range(0, $max_rating_levels);
}
public function rating( $level = null, $var = '' ) {
if( is_null( $level ) ) return wpforo_setting( 'rating', 'levels' );
$_levels = wpforo_setting( 'rating', 'levels' );
if( ! wpfkey( $_levels, $level ) ) $level = 0;
if( ! $var ) return wpforo_setting( 'rating', 'levels', $level );
return wpforo_setting( 'rating', 'levels', $level, $var );
}
/**
* @param int $points
* @param bool $percent
*
* @return int
*/
public function rating_level($points, $percent = true) {
$points = intval($points);
$max_rating_levels = (int) apply_filters('wpforo_max_rating_levels', 10);
$increment = 100 / $max_rating_levels;
for ($level = 1; $level <= $max_rating_levels; $level++) {
if ( $points < $this->rating($level, 'points') ) {
$bar = ( $level - 1 ) * $increment;
break;
}
}
// If the points are greater than or equal to the highest level's points, set $bar to 100
if ( !isset( $bar ) ) $bar = 100;
return $percent ? $bar : (int)floor($bar / (100 / $max_rating_levels) );
}
public function rating_badge( $level = 0, $view = 'short' ) {
$max_rating_levels = (int) apply_filters('wpforo_max_rating_levels', 10);
$level = ( $level > $max_rating_levels ) ? floor( $level / $max_rating_levels ) : $level;
if( $level === 0 ) {
return '';
} elseif( $level > 0 && $level < 6 ) {
if( $view == 'full' ) {
return str_repeat( ' ', $level );
} else {
return '' . esc_html( $level ) . ' ';
}
} elseif( $level > 5 && $level < 9 ) {
if( $view == 'full' ) {
return str_repeat( ' ', ( $level - 5 ) );
} else {
return '' . esc_html( $level - 5 ) . ' ';
}
}
if( $max_rating_levels > 10 ){
if( $level < 12 ) {
if( $view == 'full' ) {
return str_repeat( ' ', ( $level - 8 ) );
} else {
return '' . esc_html( $level - 8 ) . ' ';
}
} elseif( $level < 15 ) {
if( $view == 'full' ) {
return str_repeat( ' ', ( $level - 11 ) );
} else {
return '' . esc_html( $level - 11 ) . ' ';
}
}
} else {
if( $level > 8 ) {
return '';
}
}
return '';
}
public function reset( $userid ) {
if( ! $userid ) return;
wpforo_clean_cache( 'avatar', $userid );
delete_user_meta( intval( $userid ), '_wpf_member_obj' );
if( wpforo_setting( 'seo', 'seo_profile' ) ) WPF()->seo->clear_cache();
}
public function clear_db_cache() {
WPF()->db->query( "DELETE FROM `" . WPF()->db->usermeta . "` WHERE `meta_key` = '_wpf_member_obj'" );
}
private function update_online_time( $userid = null ) {
if( ! $userid ) $userid = WPF()->current_userid;
if( ! $userid ) return false;
$current_timestamp = time();
$sql = "UPDATE `" . WPF()->tables->profiles . "` SET `online_time` = %d WHERE `userid` = %d";
$sql = WPF()->db->prepare( $sql, $current_timestamp, wpforo_bigintval( $userid ) );
if( false !== WPF()->db->query( $sql ) ) return $current_timestamp;
return false;
}
public function init_current_user() {
WPF()->wp_current_user = $current_user = wp_get_current_user();
if( $current_user->exists() ) {
WPF()->current_userid = $current_user->ID;
WPF()->current_user_login = $current_user->user_login;
WPF()->current_user_email = $current_user->user_email;
WPF()->current_user_display_name = $current_user->display_name;
$user = $this->get_member( $current_user->ID );
if( ! wpfkey( $user, 'groupid' ) ) {
$this->synchronize_user( $current_user->ID );
$user = $this->get_member( $current_user->ID );
}
$user_meta = get_user_meta( $current_user->ID );
WPF()->current_user = $user;
WPF()->current_usermeta = $user_meta;
WPF()->current_user_groupid = WPF()->current_user['groupid'];
WPF()->current_user_secondary_groupids = WPF()->current_user['secondary_groupids'];
WPF()->current_user_groupids = array_unique( array_filter( array_merge( (array) WPF()->current_user_groupid, (array) WPF()->current_user_secondary_groupids ) ) );
WPF()->current_user_status = (string) wpfval($user, 'status');
$this->update_online_time();
} elseif( $guest = $this->get_guest_cookies() ) {
WPF()->current_userid = 0;
WPF()->current_user_login = '';
WPF()->current_user_email = $guest['email'];
WPF()->current_user_display_name = $guest['name'];
WPF()->current_user = $this->get_guest( $guest );
WPF()->current_usermeta = [];
WPF()->current_user_groupid = 4;
WPF()->current_user_groupids = [ 4 ];
WPF()->current_user_secondary_groupids = [];
WPF()->current_user_status = '';
WPF()->current_user_accesses = [];
}
WPF()->usergroup->init_current();
if( function_exists( 'wp_get_session_token' ) && function_exists( 'wp_parse_auth_cookie' ) ) WPF()->session_token = wp_get_session_token();
if( ! WPF()->session_token ) {
$secret_key = defined( 'SECRET_KEY' ) && SECRET_KEY ? SECRET_KEY : 'wpforo';
WPF()->session_token = hash_hmac( 'sha256', md5( (string) wpfval( $_SERVER, 'HTTP_USER_AGENT' ) ) . md5( (string) wpfval( $_SERVER, 'REMOTE_ADDR' ) ) . md5( (string) wpfval( $_SERVER, 'SERVER_ADDR' ) ), $secret_key );
}
do_action( 'wpforo_after_init_current_user', WPF()->current_user, WPF()->current_usermeta, WPF()->current_user_groupid, WPF()->current_user_secondary_groupids, WPF()->current_user_groupids );
}
public function blog_posts( $userid ) {
if( isset( $userid ) && $userid ) return count_user_posts( $userid );
return 0;
}
public function blog_comments( $userid, $user_email ) {
global $wpdb;
if( ! $userid || ! $user_email ) return 0;
return (int) $wpdb->get_var( "SELECT COUNT(*) FROM " . $wpdb->comments . " WHERE `user_id` = " . intval( $userid ) . " OR `comment_author_email` = '" . esc_sql( $user_email ) . "'" );
}
public function show_delete_form( $current_user, $userids ) {
if( empty( $current_user ) || empty( $userids ) ) return;
$userids = array_diff( $userids, [ $current_user->ID ] );
$users_have_content = false;
if( WPF()->db->get_var( "SELECT `postid` FROM `" . WPF()->tables->posts . "` WHERE `userid` IN( " . implode( ',', array_map( 'intval', $userids ) ) . " ) LIMIT 1" ) ) {
$users_have_content = true;
}
?>