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' => '',
];
$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 );
}
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' ] );
add_action( 'wpforo_before_front_delete_user', [ $this, 'buffer_before_front_delete_user' ] );
add_action( 'wpforo_after_front_delete_user', [ $this, 'after_front_delete_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'] );
sort( $member['secondary_groupids'], SORT_NUMERIC );
sort( $member['groupids'], SORT_NUMERIC );
$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'] = wp_json_encode( $member['reactions_in'] );
$member['reactions_out'] = wp_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'] = wp_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 ) {
$self = $userid === WPF()->current_userid && ! is_super_admin( $userid ) && apply_filters(
'wpforo_can_user_self_delete',
true
);
$not_self = $userid !== WPF()->current_userid && ( current_user_can( 'administrator' ) || WPF()->usergroup->can( 'dm' ) ) && WPF()->perm->user_can_manage_user(
WPF()->current_userid,
$userid
);
return $self || $not_self;
},
'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;
}
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();
// Security: extract only expected keys instead of extract()
$user_login = isset( $user_fields['user_login'] ) ? $user_fields['user_login'] : '';
$user_email = isset( $user_fields['user_email'] ) ? $user_fields['user_email'] : '';
$user_pass1 = isset( $user_fields['user_pass1'] ) ? $user_fields['user_pass1'] : '';
$user_pass2 = isset( $user_fields['user_pass2'] ) ? $user_fields['user_pass2'] : '';
$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( ! is_avatar_url( $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' ) ) ) ) {
$participant_fields_list = $this->get_participant_fields_list( $form_fields, true );
$f = $this->get_field( 'secondary_groupids' );
if(
in_array( 'secondary_groupids', $participant_fields_list )
&& ( 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 ) ) {
$privileged_roles = [ 'administrator', 'editor', 'author' ];
$safe_groupids = [];
foreach( WPF()->usergroup->get_secondary_groups() as $group ) {
if( ! in_array( $group['role'], $privileged_roles, true ) ) {
$safe_groupids[] = (int) $group['groupid'];
}
}
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, $safe_groupids, true ) ) {
$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 = wp_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 = wp_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'] ) && current_user_can( 'administrator' ) && ! 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' ) ) ) {
$secondary_groupids = array_filter( array_map( 'intval', (array) $secondary_groupids ) );
$privileged_roles = [ 'administrator', 'editor', 'author' ];
$safe_groupids = [];
foreach( WPF()->usergroup->get_secondary_groups() as $group ) {
if( ! in_array( $group['role'], $privileged_roles, true ) ) {
$safe_groupids[] = (int) $group['groupid'];
}
}
$secondary_groupids = array_filter( $secondary_groupids, function( $gid ) use ( $safe_groupids ) {
return ! in_array( $gid, [ 1, 2, 4 ], true ) && in_array( $gid, $safe_groupids, true );
} );
if( ! empty( $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( wpforo_is_id( $args ) ) {
$args = [ 'userid' => $args ];
} elseif( ! is_array( $args ) ) {
$args = [ 'user_nicename' => $args ];
}
$args = wpforo_parse_args( $args, $default );
// Security: extract only expected keys instead of extract()
$userid = $args['userid'];
$user_nicename = $args['user_nicename'];
$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 );
// Security: extract only expected keys instead of extract()
$include = $args['include'];
$exclude = $args['exclude'];
$status = $args['status'];
$groupid = $args['groupid'];
$online_time = $args['online_time'];
$orderby = $args['orderby'];
$order = $args['order'];
$offset = $args['offset'];
$row_count = $args['row_count'];
$groupids = $args['groupids'];
$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'";
$sql_count = "SELECT count(*)
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`";
$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 );
$sql_count .= " WHERE " . implode( " AND ", $wheres );
}
$item_count_sql = preg_replace( '#ORDER.+$#is', '', $sql_count );
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 );
$offset = absint( $offset );
$limit = absint( $row_count );
if( $limit ) $sql .= esc_sql( " LIMIT {$offset},{$limit}" );
return array_map( [ $this, 'decode' ], WPF()->db->get_results( $sql, ARRAY_A ) );
}
public function search( $needle, $fields = [], $limit = null, $orderby = 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'] ) {
if( $f['fieldKey'] === 'title' ) {
$wheres[] = "`" . esc_sql( $field ) . "` LIKE '" . esc_sql( $needle ) . "'";
} else {
$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( ! is_null( $orderby ) ) {
$sql .= " ORDER BY " . implode( ', ', (array) $orderby );
}
if( $limit ) $sql .= " LIMIT " . intval( $limit );
return WPF()->db->get_col( $sql );
} else {
return [];
}
} else {
return [];
}
}
public function filter( $args, $limit = null, $orderby = 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( ! is_null( $orderby ) ) {
$sql .= " ORDER BY " . implode( ', ', (array) $orderby );
}
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( float $points ): array {
$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 ): float {
$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 );
$other_points = (float) apply_filters( 'wpforo_member_get_points_other_points', 0, $member );
return $topic_points + $post_points + $like_points + $dislike_points + $other_points;
}
public function get_count( $args = [] ): int {
$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((array)$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 = WPF()->current_user['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;
}
?>