PluginProbe
wpForo Forum / 1.4.12
wpForo Forum v1.4.12
3.1.5 3.1.4 3.1.2 3.1.1 3.1.0 3.0.9 3.0.8 3.0.7 trunk 1.0.0 1.0.1 1.0.2 1.1.0 1.1.1 1.1.2 1.2.0 1.3.0 1.3.1 1.4.0 1.4.1 1.4.10 1.4.11 1.4.12 1.4.13 1.4.2 All 137 releases
wpforo / wpf-includes / class-members.php

class-members.php in wpForo Forum 1.4.12, at wpf-includes/class-members.php

2,309 lines 88.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 // Exit if accessed directly
3 if( !defined( 'ABSPATH' ) ) exit;
4
5
6 class wpForoMember{
7 public $default;
8 public $options;
9 private $fields;
10 private $countries;
11 private $timezones;
12 public $login_min_length;
13 public $login_max_length;
14 public $pass_min_length;
15 public $pass_max_length;
16
17 static $cache = array( 'users' => array(), 'user' => array(), 'guest' => array(), 'avatar' => array() );
18
19 function __construct(){
20 $this->init_defaults();
21 $this->init_options();
22
23 add_action('delete_user_form', array(&$this, 'show_delete_form'), 10, 2);
24 }
25
26 private function init_defaults(){
27 $this->default = new stdClass;
28
29 $this->default->options = array(
30 'custom_title_is_on' => 1,
31 'default_title' => 'Member',
32 'online_status_timeout' => 240,
33 'url_structure' => 'nicename',
34 'search_type' => 'search', // can to be 'search' or 'filter'
35 'login_url' => '',
36 'register_url' => '',
37 'lost_password_url' => '',
38 'redirect_url_after_login' => '',
39 'redirect_url_after_register' => '',
40 'redirect_url_after_confirm_sbscrb' => '',
41 'rating_title_ug' => array ( 1 => '0', 5 => '1', 4 => '1', 2 => '0', 3 => '1' ),
42 'rating_badge_ug' => array ( 1 => '1', 5 => '1', 4 => '1', 2 => '1', 3 => '1' ),
43 'title_usergroup' => array ( 1 => '1', 5 => '1', 4 => '1', 2 => '1', 3 => '0' )
44 );
45
46 $this->default->login_min_length = 3;
47 $this->default->login_max_length = 30;
48 $this->default->pass_min_length = 6;
49 $this->default->pass_max_length = 20;
50 }
51
52 private function init_options(){
53 $this->options = get_wpf_option('wpforo_member_options', $this->default->options);
54 if( !preg_match('#^https?://[^\r\n\t\s\0]+#isu', $this->options['redirect_url_after_login']) ) $this->options['redirect_url_after_login'] = '';
55 if( !preg_match('#^https?://[^\r\n\t\s\0]+#isu', $this->options['redirect_url_after_register']) ) $this->options['redirect_url_after_register'] = '';
56 if( !preg_match('#^https?://[^\r\n\t\s\0]+#isu', $this->options['redirect_url_after_confirm_sbscrb']) ) $this->options['redirect_url_after_confirm_sbscrb'] = '';
57
58 $this->login_min_length = $this->default->login_min_length;
59 $this->login_max_length = $this->default->login_max_length;
60 $this->pass_min_length = $this->default->pass_min_length;
61 $this->pass_max_length = $this->default->pass_max_length;
62 }
63
64 public function get_cache( $var ){
65 if( isset(self::$cache[$var]) ) return self::$cache[$var];
66 }
67
68 public function send_new_user_notifications($user_id, $notify = 'admin'){
69 wp_send_new_user_notifications( $user_id, $notify );
70 }
71
72 private function add_profile($args){
73 if(empty($args)) return FALSE;
74 if(!isset($args['userid']) || !$args['userid'] || !isset($args['username']) || !$args['username'] ) return FALSE;
75 extract( $args, EXTR_OVERWRITE );
76 $this->reset($userid);
77 return WPF()->db->insert(
78 WPF()->tables->profiles,
79 array( 'userid' => intval($userid),
80 'title' => ( isset($title) && $title ? $title : WPF()->member->options['default_title'] ),
81 'username' => sanitize_user($username),
82 'groupid' => intval((isset($groupid) && $groupid ? $groupid : WPF()->usergroup->default_groupid)),
83 'site' => (isset($site) ? sanitize_text_field($site) : '' ),
84 'timezone' => ( isset($timezone) ? sanitize_text_field($timezone) : 'UTC+0' ),
85 'about' => ( isset($about) ? stripslashes( wpforo_kses(trim($about), 'user_description') ) : '' ),
86 'last_login' => ( isset($last_login) ? $last_login : current_time('mysql', 1) ) ),
87 array( '%d', '%s', '%s', '%d', '%s', '%s', '%s', '%s' )
88 );
89 }
90
91 function edit_profile($args){
92 if(empty($args)) return FALSE;
93 if( !isset($args['userid']) || !$args['userid'] ) return FALSE;
94 extract( $args, EXTR_OVERWRITE );
95
96 $fields = array();
97 $fields_types = array();
98
99 if(isset($last_login) && $last_login){
100 $fields['last_login'] = sanitize_text_field($last_login);
101 $fields_types[] = '%s';
102 }
103
104 if(isset($groupid) && $groupid){
105 $groupid = intval($groupid);
106 if( !(!WPF()->current_object['user_is_same_current_user'] && (WPF()->current_user_groupid == 1 || current_user_can('administrator') )) ) {
107 $flds = $this->get_fields();
108 if( !in_array($groupid, wpforo_parse_args($flds['groupid']['allowedGroupIds'])) ) $groupid = WPF()->usergroup->default_groupid;
109 }
110 $fields['groupid'] = $groupid;
111 $fields_types[] = '%d';
112 }
113
114 if(isset($title) && $title){
115 $fields['title'] = sanitize_text_field(trim($title));
116 $fields_types[] = '%s';
117 }
118 if(isset($site)){
119 $fields['site'] = sanitize_text_field(trim($site));
120 $fields_types[] = '%s';
121 }
122 if(isset($icq)){
123 $fields['icq'] = sanitize_text_field(trim($icq));
124 $fields_types[] = '%s';
125 }
126 if(isset($aim)){
127 $fields['aim'] = sanitize_text_field(trim($aim));
128 $fields_types[] = '%s';
129 }
130 if(isset($yahoo)){
131 $fields['yahoo'] = sanitize_text_field(trim($yahoo));
132 $fields_types[] = '%s';
133 }
134 if(isset($msn)){
135 $fields['msn'] = sanitize_text_field(trim($msn));
136 $fields_types[] = '%s';
137 }
138 if(isset($facebook)){
139 $fields['facebook'] = sanitize_text_field(trim($facebook));
140 $fields_types[] = '%s';
141 }
142 if(isset($twitter)){
143 $fields['twitter'] = sanitize_text_field(trim($twitter));
144 $fields_types[] = '%s';
145 }
146 if(isset($gtalk)){
147 $fields['gtalk'] = sanitize_text_field(trim($gtalk));
148 $fields_types[] = '%s';
149 }
150 if(isset($skype)){
151 $fields['skype'] = sanitize_text_field(trim($skype));
152 $fields_types[] = '%s';
153 }
154 if(isset($signature)){
155 $fields['signature'] = stripslashes(wpforo_kses(trim($signature), 'user_description'));
156 $fields_types[] = '%s';
157 }
158 if(isset($about)){
159 $fields['about'] = stripslashes(wpforo_kses(trim($about), 'user_description'));
160 $fields_types[] = '%s';
161 }
162 if(isset($occupation)){
163 $fields['occupation'] = stripslashes(sanitize_text_field(trim($occupation)));
164 $fields_types[] = '%s';
165 }
166 if(isset($location)){
167 $fields['location'] = stripslashes(sanitize_text_field(trim($location)));
168 $fields_types[] = '%s';
169 }
170 if(isset($timezone)){
171 $fields['timezone'] = sanitize_text_field(trim($timezone));
172 $fields_types[] = '%s';
173 }
174 if(isset($avatar_type) && $avatar_type != 'gravatar' && isset($avatar_url) && $avatar_url){
175 $fields['avatar'] = esc_url(trim($avatar_url));
176 $fields_types[] = '%s';
177 }
178 if(isset($avatar_type) && $avatar_type == 'gravatar'){
179 $fields['avatar'] = '';
180 $fields_types[] = '%s';
181 }
182
183 $this->reset($userid);
184
185 $result = true;
186 if($fields){
187 $result = WPF()->db->update(
188 WPF()->tables->profiles,
189 $fields,
190 array('userid' => intval($userid)),
191 $fields_types,
192 array('%d')
193 );
194
195 if( $result !== FALSE && $userid ){
196 if(isset($fields['site'])){
197 WPF()->db->query("UPDATE `".WPF()->db->users."` SET `user_url` = '" . esc_sql($fields['site']) . "' WHERE `ID` = " . intval($userid) );
198 }
199 if(isset($fields['about'])){
200 update_user_meta( $userid, 'description', $fields['about'] );
201 }
202 }
203 }
204
205 return $result;
206 }
207
208 function create($args){
209 if(!wpforo_feature('user-register')){
210 WPF()->notice->add('User registration is disabled.', 'error');
211 return FALSE;
212 }
213
214 $args = apply_filters( 'wpforo_create_profile', $args );
215
216 if( (isset($args['error']) && $args['error']) || !$args ){
217 return FALSE;
218 }
219
220 $this->login_min_length = apply_filters('wpforo_login_min_length', $this->login_min_length);
221 $this->login_max_length = apply_filters('wpforo_login_max_length', $this->login_max_length);
222 $this->pass_min_length = apply_filters('wpforo_pass_min_length', $this->pass_min_length);
223 $this->pass_max_length = apply_filters('wpforo_pass_max_length', $this->pass_max_length);
224
225 if( !empty($args) && is_array($args) && !empty($args['user_pass1']) ){
226 remove_action('register_new_user', 'wp_send_new_user_notifications');
227 add_action('register_new_user', array($this, 'send_new_user_notifications'));
228
229 do_action( 'wpforo_create_profile_before', $args );
230
231 $errors = new WP_Error();
232
233 extract($args, EXTR_OVERWRITE);
234 $sanitized_user_login = sanitize_user( $user_login );
235 $user_email = apply_filters( 'user_registration_email', $user_email );
236 $user_pass1 = trim(substr($user_pass1, 0, 100));
237 $user_pass2 = trim(substr($user_pass2, 0, 100));
238 $illegal_user_logins = array_map( 'strtolower', (array) apply_filters( 'illegal_user_logins', array() ) );
239 if ( $sanitized_user_login == '' ) {
240 $errors->add( 'empty_username', __( '<strong>ERROR</strong>: Please enter a username.' ) );
241 WPF()->notice->add('Username is missed.', 'error');
242 return FALSE;
243 }elseif ( ! validate_username( $user_login ) ) {
244 $errors->add( 'invalid_username', __( '<strong>ERROR</strong>: This username is invalid because it uses illegal characters. Please enter a valid username.' ) );
245 $sanitized_user_login = '';
246 WPF()->notice->add('Illegal character in username.', 'error');
247 $user_login = '';
248 return FALSE;
249 }elseif( strlen($user_login) < $this->login_min_length || strlen($user_login) > $this->login_max_length ){
250 WPF()->notice->add( 'Username length must be between %d characters and %d characters.', 'error', array($this->login_min_length, $this->login_max_length) );
251 return FALSE;
252 }elseif ( username_exists( $sanitized_user_login ) ) {
253 $errors->add( 'username_exists', __( '<strong>ERROR</strong>: This username is already registered. Please choose another one.' ) );
254 WPF()->notice->add('Username exists. Please insert another.', 'error');
255 return FALSE;
256 }elseif ( in_array( strtolower( $sanitized_user_login ), $illegal_user_logins ) ) {
257 $errors->add( 'invalid_username', __( '<strong>ERROR</strong>: Sorry, that username is not allowed.' ) );
258 WPF()->notice->add('ERROR: invalid_username. Sorry, that username is not allowed. Please insert another.', 'error');
259 return FALSE;
260 }elseif ( $user_email == '' ) {
261 $errors->add( 'empty_email', __( '<strong>ERROR</strong>: Please type your email address.' ) );
262 WPF()->notice->add('Insert your Email address.', 'error');
263 return FALSE;
264 }elseif ( ! is_email( $user_email ) ) {
265 $errors->add( 'invalid_email', __( '<strong>ERROR</strong>: The email address isn&#8217;t correct.' ) );
266 WPF()->notice->add('Invalid Email address', 'error');
267 $user_email = '';
268 return FALSE;
269 }elseif ( email_exists( $user_email ) ) {
270 $errors->add( 'email_exists', __( '<strong>ERROR</strong>: This email is already registered, please choose another one.' ) );
271 WPF()->notice->add('Email address exists. Please insert another.', 'error');
272 return FALSE;
273 }elseif( strlen($user_pass1) < $this->pass_min_length || strlen($user_pass1) > $this->pass_max_length ){
274 WPF()->notice->add( 'Password length must be between %d characters and %d characters.', 'error', array($this->pass_min_length, $this->pass_max_length) );
275 return FALSE;
276 }elseif($user_pass1 != $user_pass2){
277 WPF()->notice->add('Password mismatch.', 'error');
278 return FALSE;
279 }else{
280 do_action( 'register_post', $sanitized_user_login, $user_email, $errors );
281 $errors = apply_filters( 'registration_errors', $errors, $sanitized_user_login, $user_email );
282 if ( $errors->get_error_code() ){
283 $args = array();
284 foreach($errors->errors as $u_err) $args[] = $u_err[0];
285 WPF()->notice->add($args, 'error');
286 return FALSE;
287 }
288 $user_id = wp_create_user( $sanitized_user_login, $user_pass1, $user_email );
289 if ( !is_wp_error( $user_id ) && $user_id ) {
290 $args['userid'] = $user_id;
291 $creds = array('user_login' => $sanitized_user_login, 'user_password' => $user_pass1 );
292 wp_signon($creds);
293 do_action( 'wpforo_create_profile_after', $args );
294 do_action( 'register_new_user', $user_id );
295 WPF()->notice->add('Success! Thank you Dear Friend', 'success');
296 return $user_id;
297 }
298 }
299 }elseif( !empty($args['user_login']) && !empty($args['user_email']) ){
300 if( strlen($args['user_login']) < $this->login_min_length || strlen($args['user_login']) > $this->login_max_length ){
301 WPF()->notice->add( 'Username length must be between %d characters and %d characters.', 'error', array($this->login_min_length, $this->login_max_length) );
302 return FALSE;
303 }
304 $user_id = register_new_user( $args['user_login'], $args['user_email'] );
305 if ( !is_wp_error( $user_id ) && $user_id ) {
306 $args['userid'] = $user_id;
307 do_action( 'wpforo_create_profile_after', $args );
308 WPF()->notice->add('Success! Please check your mail for confirmation.', 'success');
309 return $user_id;
310 }
311 }
312 if(!empty($user_id->errors)){
313 $args = array();
314 foreach($user_id->errors as $u_err) $args[] = $u_err[0];
315 WPF()->notice->add($args, 'error');
316 return FALSE;
317 }
318 WPF()->notice->add('Registration Error', 'error');
319 return FALSE;
320 }
321
322 function edit( $args = array() ){
323 if( empty($args) && empty($_REQUEST['member']) ) return FALSE;
324 if( empty($args) && !empty($_REQUEST['member']) ) $args = $_REQUEST['member'];
325
326 $args = apply_filters( 'wpforo_edit_profile', $args );
327 do_action( 'wpforo_edit_profile_before', $args );
328
329 if( (isset($args['error']) && $args['error']) || !$args ){
330 return FALSE;
331 }
332
333 extract($args, EXTR_OVERWRITE);
334
335 $fields = array();
336 $fields_types = array();
337
338 if( isset($userid) && $userid ){
339 $userid = intval($userid);
340
341 $isRegister = ( isset($args['template']) && $args['template'] == 'register' ) ? true : false;
342 if ( !$isRegister && ( !is_user_logged_in() || !WPF()->perm->user_can_manage_user( WPF()->current_userid, $userid ) ) ) {
343 WPF()->notice->add('Permission denied', 'error');
344 return FALSE;
345 }
346
347 if( isset($display_name) && $display_name ){
348 $fields['display_name'] = sanitize_text_field(trim($display_name));
349 $fields_types[] = '%s';
350 }
351 if( isset($user_email) && $user_email ){
352 $user_email = sanitize_email($user_email);
353 if ( ! is_email( $user_email ) ) {
354 WPF()->notice->add('Invalid Email address', 'error');
355 return FALSE;
356 }elseif ( ( $owner_id = email_exists( $user_email ) ) && ( $owner_id != $userid ) ) {
357 WPF()->notice->add('This email address is already registered. Please insert another.', 'error');
358 return FALSE;
359 }
360
361 $fields['user_email'] = $user_email;
362 $fields_types[] = '%s';
363 }
364 if( isset($user_nicename) && $user_nicename ){
365 $user_nicename = sanitize_title( trim($user_nicename) );
366 if( is_numeric($user_nicename) ){
367 WPF()->notice->add('Numerical nicknames are not allowed. Please insert another.', 'error');
368 return FALSE;
369 }
370 $sql = "SELECT `ID` FROM `".WPF()->db->users."` WHERE `ID` != ". intval($userid) ." AND ( `user_nicename` LIKE '".esc_sql($user_nicename)."' OR `ID` LIKE '".esc_sql($user_nicename)."' )";
371 if( WPF()->db->get_var($sql)){
372 WPF()->notice->add('This nickname is already registered. Please insert another.', 'error');
373 return FALSE;
374 }
375
376 $fields['user_nicename'] = $user_nicename;
377 $fields_types[] = '%s';
378
379 WPF()->db->update(
380 WPF()->db->usermeta,
381 array('meta_value' => $user_nicename),
382 array('user_id' => $userid, 'meta_key' => 'nickname'),
383 array('%s'),
384 array('%d', '%s')
385 );
386 }
387
388 if( $fields ){
389 WPF()->db->update(
390 WPF()->db->users,
391 $fields,
392 array('ID' => $userid),
393 $fields_types,
394 array('%d')
395 );
396
397 $this->reset($userid);
398 }
399
400 if( FALSE !== $this->edit_profile($args) ){
401 do_action( 'wpforo_edit_profile_after', $args );
402 WPF()->notice->add('Your profile data have been successfully updated.', 'success');
403 return $userid;
404 }
405 }
406
407 WPF()->notice->add('Something wrong with profile data.', 'error');
408 return FALSE;
409 }
410
411 public function change_password($old_passw, $new_passw, $userid){
412 if( !$userid = wpforo_bigintval($userid) ){
413 WPF()->notice->clear();
414 WPF()->notice->add('Userid is wrong', 'error');
415 return false;
416 }
417
418 $user = $this->get_member($userid);
419 if( !apply_filters('wpforo_change_password_validate', true, $old_passw, $new_passw, $user) ) return false;
420
421 if ( wp_check_password( $old_passw, $user['user_pass'], $userid) ){
422 wp_set_password( $new_passw, $userid );
423
424 /**
425 * Login user after change password with new pass
426 */
427 $creds = array('user_login' => sanitize_user( $user['user_login'] ), 'user_password' => $new_passw );
428 wp_signon($creds);
429
430 WPF()->notice->add('Password successfully changed', 'success');
431 return true;
432 }
433
434 WPF()->notice->clear();
435 WPF()->notice->add('Old password is wrong', 'error');
436 return false;
437 }
438
439 function upload_avatar( $userid = 0 ){
440
441 $userid = intval($userid);
442 if( !WPF()->perm->usergroup_can('upa') ) return;
443
444 if( !$userid ){
445 if( !isset($_POST['member']['userid']) || !$userid = intval($_POST['member']['userid']) ) return;
446 }
447
448 if( !$user = $this->get_member($userid) ) return;
449 $user_nicename = urldecode($user['user_nicename']);
450 if(isset($_FILES['avatar']) && !empty($_FILES['avatar']) && isset($_FILES['avatar']['name']) && $_FILES['avatar']['name']){
451
452 $name = sanitize_file_name($_FILES['avatar']['name']); //myimg.png
453 $type = sanitize_mime_type($_FILES['avatar']['type']); //image/png
454 $tmp_name = sanitize_text_field($_FILES['avatar']['tmp_name']); //D:\wamp\tmp\php986B.tmp
455 $error = sanitize_text_field($_FILES['avatar']['error']); //0
456 $size = intval($_FILES['avatar']['size']); //6112
457
458 if( $size > 2*1048576 ){
459 WPF()->notice->clear();
460 WPF()->notice->add('Avatar image is too big maximum allowed size is 2MB', 'error');
461 return FALSE;
462 }
463
464 if( $error ){
465 $error = wpforo_file_upload_error($error);
466 WPF()->notice->clear();
467 WPF()->notice->add($error, 'error');
468 return FALSE;
469 }
470
471 $upload_dir = wp_upload_dir();
472 $uplds_dir = $upload_dir['basedir']."/wpforo";
473 $avatar_dir = $upload_dir['basedir']."/wpforo/avatars";
474 if(!is_dir($uplds_dir)) wp_mkdir_p($uplds_dir);
475 if(!is_dir($avatar_dir)) wp_mkdir_p($avatar_dir);
476
477 $ext = pathinfo($name, PATHINFO_EXTENSION);
478 if( !wpforo_is_image($ext) ){
479 WPF()->notice->clear();
480 WPF()->notice->add('Incorrect file format. Allowed formats: jpeg, jpg, png, gif.', 'error');
481 return FALSE;
482 }
483
484 $fnm = pathinfo($user_nicename, PATHINFO_FILENAME);
485 $fnm = str_replace(' ', '-', $fnm);
486 while(strpos($fnm, '--') !== FALSE) $fnm = str_replace('--', '-', $fnm);
487 $fnm = preg_replace("/[^-a-zA-Z0-9]/", "", $fnm);
488 $fnm = trim($fnm, "-");
489
490 $avatar_fname = $fnm . ( $fnm ? '_' : '' ) . $userid . "." . strtolower($ext);
491 $avatar_fname_orig = $fnm . ( $fnm ? '_' : '' ) . $userid . "." . $ext;
492 $avatar_path = $avatar_dir . "/" . $avatar_fname;
493 $avatar_path_orig = $avatar_dir . "/" . $avatar_fname_orig;
494
495 if(is_dir($avatar_dir)){
496 if(move_uploaded_file($tmp_name, $avatar_path)) {
497 $image = wp_get_image_editor( $avatar_path );
498 if ( ! is_wp_error( $image ) ) {
499 $image->resize( 150, 150, true );
500 $saved = $image->save( $avatar_path );
501 if(! is_wp_error( $saved ) && $avatar_fname != $avatar_fname_orig ) {
502 if ( defined (PHP_OS) && strtoupper(substr(PHP_OS, 0, 3)) !== 'WIN') unlink( $avatar_path_orig );
503 }
504 }
505 $blog_url = preg_replace('#^https?\:#is', '', $upload_dir['baseurl']);
506 WPF()->db->update(WPF()->tables->profiles, array('avatar' => $blog_url . "/wpforo/avatars/" . $avatar_fname), array('userid' => intval($userid)), array('%s'), array('%d'));
507 $this->reset($userid);
508 }
509 }
510 }
511 }
512
513 function synchronize_user($userid){
514 if(!$userid) return FALSE;
515 $user = get_userdata($userid);
516 if( is_super_admin( $userid ) || in_array('administrator', $user->roles) ){
517 $groupid = 1;
518 }elseif( in_array('editor', $user->roles) ){
519 $groupid = 2;
520 }elseif( in_array('customer', $user->roles) ){
521 $groupid = 5;
522 }else{
523 $groupid = WPF()->usergroup->default_groupid;
524 }
525 $insert_groupid = (isset($_POST['wpforo_usergroup'])) ? intval($_POST['wpforo_usergroup']) : $groupid;
526 $insert_timezone = (isset($_POST['wpforo_usertimezone'])) ? sanitize_text_field($_POST['wpforo_usertimezone']) : '';
527 $about = get_user_meta( $userid, 'description', true );
528 return $this->add_profile(
529 array( 'userid' => wpforo_bigintval($userid),
530 'username' => sanitize_user($user->user_login),
531 'groupid' => intval($insert_groupid),
532 'site' => esc_url($user->user_url),
533 'timezone' => sanitize_text_field($insert_timezone),
534 'about' => stripslashes( wpforo_kses(trim($about), 'user_description') ),
535 'last_login' => sanitize_text_field($user->user_registered) ) );
536 }
537
538 function synchronize_users(){
539
540 if( is_multisite() ){
541 $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."` )";
542 } else {
543 $sql = "SELECT `ID` as user_id FROM `".WPF()->db->users."` WHERE `ID` NOT IN( SELECT `userid` FROM `".WPF()->tables->profiles."` )";
544 }
545 $userids = WPF()->db->get_col($sql);
546 if( !empty($userids) ){
547 foreach($userids as $userid){
548 $this->synchronize_user($userid);
549 }
550 }
551
552 ## -- START -- delete profiles where not participant on multisite blog
553 if( is_multisite() ){
554 $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' )";
555 WPF()->db->query($sql);
556 }
557 ## -- END -- delete profiles where not participant on multisite blog
558 }
559
560 function get_member($args){
561 if(!$args) return $this->get_guest();
562
563 $cache = WPF()->cache->on('memory_cashe');
564
565 $default = array(
566 'userid' => NULL, // $userid
567 'user_nicename' => '' // $user_nicename
568 );
569
570 if( is_numeric($args) ){
571 $args = array( 'userid' => $args );
572 }elseif ( !is_array($args) ){
573 $args = array( 'user_nicename' => $args );
574 }
575
576 $args = wpforo_parse_args( $args, $default );
577
578 if(isset($args['userid'])){
579 if( $cache && isset(self::$cache['user'][$args['userid']]) ){
580 return self::$cache['user'][$args['userid']];
581 }
582 }
583
584 extract($args);
585
586 $do_db_cache = wpforo_feature('member_cashe');
587
588 $userid = wpforo_bigintval($userid);
589
590 $user_meta_obj = true;
591 $member = array();
592 if( $do_db_cache ){
593 if( $user_nicename ){
594 $user_obj = get_user_by( 'user_nicename', $user_nicename );
595 if( !empty($user_obj) ) $userid = $user_obj->ID;
596 }
597 $member = get_user_meta( $userid, '_wpf_member_obj', true );
598 }
599
600 if(empty($member)){
601 $user_meta_obj = false;
602 $sql = "SELECT *, ug.name AS groupname, ug.color AS color FROM `".WPF()->db->users."` u
603 INNER JOIN `".WPF()->tables->profiles."` p ON p.`userid` = u.`ID`
604 LEFT JOIN `".WPF()->tables->usergroups."` ug ON ug.`groupid` = p.`groupid`";
605 $wheres = array();
606 if($userid) $wheres[] = "`ID` = $userid";
607 if($user_nicename) $wheres[] = "`user_nicename` = '" . esc_sql($user_nicename) . "'";
608 if( !empty($wheres) ) $sql .= " WHERE " . implode($wheres, " AND ");
609 $member = WPF()->db->get_row($sql, ARRAY_A);
610 }
611
612 if(!empty($member)) {
613 $member['profile_url'] = $this->profile_url( $member );
614 $member['stat'] = $this->get_stat( $member, false, true );
615 if( $do_db_cache ){
616 if(!$user_meta_obj) update_user_meta( $userid, '_wpf_member_obj', $member );
617 }
618 }
619
620 if($cache && isset($userid) && $member){
621 return self::$cache['user'][$userid] = $member;
622 }else{
623 return $member;
624 }
625 }
626
627 function get_members($args = array(), &$items_count = 0){
628
629 $default = array(
630 'include' => array(), // array( 2, 10, 25 )
631 'exclude' => array(), // array( 2, 10, 25 )
632 'status' => array('active', 'banned'), // 'active', 'blocked', 'trashed', 'spamer'
633 'groupid' => NULL, // groupid
634 'online_time' => NULL, // groupid
635 'orderby' => 'userid', //
636 'order' => 'ASC', // ASC DESC
637 'offset' => 0, // OFFSET
638 'row_count' => NULL, // ROW COUNT
639 'groupids' => array(), // array( 1, 2 )
640 );
641
642 $args = wpforo_parse_args( $args, $default );
643 if(!empty($args)){
644 extract($args, EXTR_OVERWRITE);
645
646 $include = wpforo_parse_args( $include );
647 $exclude = wpforo_parse_args( $exclude );
648
649 $sql = "SELECT *, ug.name AS groupname, ug.color AS color FROM `".WPF()->db->users."` u
650 INNER JOIN `".WPF()->tables->profiles."` p ON p.`userid` = u.`ID`
651 LEFT JOIN `".WPF()->tables->usergroups."` ug ON ug.`groupid` = p.`groupid`";
652 $wheres = array();
653 if(!empty($include)) $wheres[] = " u.`ID` IN(" . implode(', ', array_map('intval', $include)) . ")";
654 if(!empty($exclude)) $wheres[] = " u.`ID` NOT IN(" . implode(', ', array_map('intval', $exclude)) . ")";
655 if(!empty($status)) $wheres[] = " p.`status` IN('" . implode("','", array_map('esc_sql', array_map('sanitize_text_field', $status)) ) . "')";
656 if(!empty($groupids)) $wheres[] = " p.`groupid` IN(" . implode(', ', array_map('intval', $groupids)) . ")";
657 if(!is_null($groupid)) $wheres[] = " p.`groupid` = " . intval($groupid);
658 if(!is_null($online_time)) $wheres[] = " p.`online_time` > " . intval($online_time);
659
660 if(!empty($wheres)) $sql .= " WHERE " . implode($wheres, " AND ");
661
662 $item_count_sql = preg_replace('#SELECT.+?FROM#isu', 'SELECT count(*) FROM', $sql);
663 if( $item_count_sql ) $items_count = WPF()->db->get_var($item_count_sql);
664
665 if( $orderby == 'groupid' ) $orderby = 'p.`groupid`';
666 $sql .= esc_sql(" ORDER BY $orderby " . $order);
667 if($row_count) $sql .= esc_sql(" LIMIT $offset,$row_count");
668
669 return WPF()->db->get_results($sql, ARRAY_A);
670 }
671 }
672
673 function search($needle, $fields = array(), $limit = NULL){
674
675 if($needle != ''){
676 $needle = sanitize_text_field($needle);
677 if(empty($fields)){
678 $fields = array(
679 'title',
680 'user_nicename',
681 'user_email',
682 'signature'
683 );
684 }
685
686 $sql = "SELECT `ID` FROM `".WPF()->db->users."` u
687 INNER JOIN `".WPF()->tables->profiles."` p ON p.`userid` = u.`ID`";
688 $wheres = array();
689
690 foreach($fields as $field){
691 $field = sanitize_text_field($field);
692 $wheres[] = "`".esc_sql($field)."` LIKE '%" . esc_sql($needle) ."%'";
693 }
694
695 if(!empty($wheres)){
696 $sql .= " WHERE " . implode($wheres, " OR ");
697 if( $limit ) $sql .= " LIMIT " . intval($limit);
698
699 return WPF()->db->get_col($sql);
700 }else{
701 return array();
702 }
703 }else{
704 return array();
705 }
706
707 }
708
709 public function filter($args, $limit = NULL){
710 if($args && is_array($args)){
711 $sql = "SELECT `ID` FROM `".WPF()->db->users."` u
712 INNER JOIN `".WPF()->tables->profiles."` p ON p.`userid` = u.`ID`";
713 $wheres = array();
714
715 foreach($args as $field => $needle){
716 $field = sanitize_text_field($field);
717 $needle = sanitize_text_field($needle);
718 $wheres[] = "`".esc_sql($field)."` LIKE '%" . esc_sql($needle) ."%'";
719 }
720
721 if($wheres){
722 $sql .= " WHERE " . implode($wheres, " AND ");
723 if( $limit ) $sql .= " LIMIT " . intval($limit);
724
725 return WPF()->db->get_col($sql);
726 }
727 }
728
729 return array();
730 }
731
732 function ban($userid){
733 if( $userid == WPF()->current_userid ){
734 WPF()->notice->add('You can\'t make yourself banned user', 'error');
735 return FALSE;
736 }
737 if( !WPF()->perm->usergroup_can('bm') || !WPF()->perm->user_can_manage_user( WPF()->current_userid, intval( $userid ) )){
738 WPF()->notice->add('Permission denied for this action', 'error');
739 return FALSE;
740 }
741 if( FALSE !== WPF()->db->update(
742 WPF()->tables->profiles,
743 array('status' => 'banned'),
744 array('userid' => intval( $userid )),
745 array('%s'),
746 array('%d')
747 )
748 ){
749 $this->reset($userid);
750 WPF()->notice->add('User successfully banned from wpforo', 'success');
751 return TRUE;
752 }
753
754 WPF()->notice->add('User ban action error', 'error');
755 return FALSE;
756 }
757
758 function unban($userid){
759 if( !WPF()->perm->usergroup_can('bm') || !WPF()->perm->user_can_manage_user( WPF()->current_userid, intval( $userid ) )){
760 WPF()->notice->add('Permission denied for this action', 'error');
761 return FALSE;
762 }
763 if( FALSE !== WPF()->db->update(
764 WPF()->tables->profiles,
765 array('status' => 'active'),
766 array('userid' => intval( $userid )),
767 array('%s'),
768 array('%d')
769 )
770 ){
771 $this->reset($userid);
772 WPF()->notice->add('User successfully unbanned from wpforo', 'success');
773 return TRUE;
774 }
775
776 WPF()->notice->add('User unban action error', 'error');
777 return FALSE;
778 }
779
780 /**
781 *
782 * @param int $userid
783 * @param int $reassign
784 *
785 * @return bool true | false if user successfully deleted
786 */
787 public function delete( $userid, $reassign = NULL ){
788 if( !($userid = intval($userid)) ) return FALSE;
789 if( !WPF()->perm->usergroup_can('dm') || !WPF()->perm->user_can_manage_user( WPF()->current_userid, intval( $userid ) )){
790 WPF()->notice->add('Permission denied for this action', 'error');
791 return FALSE;
792 }
793
794 do_action('wpforo_before_delete_user', $userid, $reassign);
795
796 if( !($reassign = intval($reassign)) ){
797 if( $postids = WPF()->db->get_col( WPF()->db->prepare( "SELECT `postid` FROM `".WPF()->tables->posts."` WHERE userid = %d", $userid ) ) ){
798 foreach( $postids as $postid ) WPF()->post->delete($postid);
799 }
800
801 if( $topicids = WPF()->db->get_col( WPF()->db->prepare( "SELECT `topicid` FROM `".WPF()->tables->topics."` WHERE userid = %d", $userid ) ) ){
802 foreach( $topicids as $topicid ) WPF()->topic->delete($topicid, false);
803 }
804 }else{
805 WPF()->db->update( WPF()->tables->topics, array('userid' => $reassign), array('userid' => $userid) );
806 WPF()->db->update( WPF()->tables->posts, array('userid' => $reassign), array('userid' => $userid) );
807 WPF()->db->update( WPF()->tables->likes, array('post_userid' => $reassign), array('post_userid' => $userid) );
808 WPF()->db->update( WPF()->tables->votes, array('post_userid' => $reassign), array('post_userid' => $userid) );
809 if( $user_stats = WPF()->db->get_row(
810 WPF()->db->prepare( "SELECT
811 SUM(`posts`) AS posts,
812 SUM(`questions`) AS questions,
813 SUM(`answers`) AS answers,
814 SUM(`comments`) AS comments
815 FROM `".WPF()->tables->profiles."`
816 WHERE `userid` IN( %d , %d )", $userid, $reassign
817 ),
818 ARRAY_A
819 )
820 ){
821 WPF()->db->update(
822 WPF()->tables->profiles,
823 array(
824 'posts' => $user_stats['posts'],
825 'questions' => $user_stats['questions'],
826 'answers' => $user_stats['answers'],
827 'comments' => $user_stats['comments']
828 ),
829 array('userid' => $reassign),
830 array('%d','%d','%d','%d'),
831 array('%d')
832 );
833 }
834 }
835
836 WPF()->db->delete(
837 WPF()->tables->subscribes, array( 'userid' => $userid ), array( '%d' )
838 );
839
840 WPF()->db->delete(
841 WPF()->tables->views, array( 'userid' => $userid ), array( '%d' )
842 );
843
844 WPF()->db->delete(
845 WPF()->tables->likes, array( 'userid' => $userid ), array( '%d' )
846 );
847
848 WPF()->db->delete(
849 WPF()->tables->votes, array( 'userid' => $userid ), array( '%d' )
850 );
851
852 if( FALSE !== WPF()->db->delete(
853 WPF()->tables->profiles, array( 'userid' => $userid ), array( '%d' )
854 )
855 ){
856
857 do_action('wpforo_after_delete_user', $userid, $reassign);
858
859 WPF()->notice->add('User successfully deleted from wpforo', 'success');
860 return TRUE;
861 }
862
863 WPF()->notice->add('User delete error', 'error');
864 return FALSE;
865 }
866
867 public function avatar($member, $attr = '', $size = ''){
868
869 if(!isset($member['userid'])) return '';
870 $cache = WPF()->cache->on('memory_cashe');
871
872 $src = $member['avatar'];
873 $userid = ( $member['userid'] ? $member['userid'] : $member['user_email'] );
874 if($cache && isset(self::$cache['avatar'][$userid])){
875 if(self::$cache['avatar'][$userid]['attr'] == $attr && self::$cache['avatar'][$userid]['size'] == $size){
876 if(isset(self::$cache['avatar'][$userid]['img'])){
877 return self::$cache['avatar'][$userid]['img'];
878 }
879 }
880 }
881 if($src && wpforo_feature('custom-avatars')){
882 $attr = ($attr ? $attr : 'height="96" width="96"');
883 $img = '<img class="avatar" src="'.esc_url($src).'" '. $attr .' />';
884 }else{
885 $img = ($size) ? get_avatar($userid, $size) : get_avatar($userid);
886 if($attr) $img = str_replace('<img', '<img ' . $attr, $img);
887 }
888 if($cache){
889 self::$cache['avatar'][$userid]['attr'] = $attr;
890 self::$cache['avatar'][$userid]['size'] = $size;
891 return self::$cache['avatar'][$userid]['img'] = $img;
892 }
893 else{
894 return $img;
895 }
896 }
897
898 function get_avatar($userid, $attr = '', $size = ''){
899
900 $cache = WPF()->cache->on('memory_cashe');
901
902 if($cache && isset(self::$cache['avatar'][$userid])){
903 if(self::$cache['avatar'][$userid]['attr'] == $attr && self::$cache['avatar'][$userid]['size'] == $size){
904 if(isset(self::$cache['avatar'][$userid]['img'])){
905 return self::$cache['avatar'][$userid]['img'];
906 }
907 }
908 }
909 $src = $this->get_avatar_url($userid);
910 if($src && wpforo_feature('custom-avatars')){
911 $attr = ($attr ? $attr : 'height="96" width="96"');
912 $img = '<img class="avatar" src="'.esc_url($src).'" '. $attr .' />';
913 }else{
914 $img = ($size) ? get_avatar($userid, $size) : get_avatar($userid);
915 if($attr) $img = str_replace('<img', '<img ' . $attr, $img);
916 }
917 if($cache){
918 self::$cache['avatar'][$userid]['attr'] = $attr;
919 self::$cache['avatar'][$userid]['size'] = $size;
920 return self::$cache['avatar'][$userid]['img'] = $img;
921 }
922 else{
923 return $img;
924 }
925 }
926
927 public function get_avatar_url($userid){
928 $cache = WPF()->cache->on('memory_cashe');
929 if( $cache && array_key_exists($userid, self::$cache['user']) && array_key_exists('avatar', self::$cache['user'][$userid]) ){
930 return self::$cache['user'][$userid]['avatar'];
931 }
932 if( $cache && array_key_exists($userid, self::$cache['avatar']) && array_key_exists('avatar_url', self::$cache['avatar'][$userid]) ){
933 return self::$cache['avatar'][$userid]['avatar_url'];
934 }
935
936 $avatar_url = WPF()->db->get_var( WPF()->db->prepare("SELECT `avatar` FROM `".WPF()->tables->profiles."` WHERE `userid` = %d", wpforo_bigintval($userid)) );
937
938 if($cache) return self::$cache['avatar'][$userid]['avatar_url'] = $avatar_url;
939 return $avatar_url;
940 }
941
942 function get_topics_count( $userid ){
943 $count = WPF()->db->get_var("SELECT count(topicid) FROM `".WPF()->tables->topics."` WHERE `userid` = ".intval($userid));
944 return $count;
945 }
946
947 function get_questions_count( $userid ){
948 $count = WPF()->db->get_var("SELECT count(topicid) FROM `".WPF()->tables->topics."` WHERE `userid` = ".intval($userid));
949 return $count;
950 }
951
952 function get_answers_count( $userid ){
953 $count = WPF()->db->get_var("SELECT count(postid) FROM `".WPF()->tables->posts."` WHERE `is_answer` = 1 AND `userid` = ".intval($userid));
954 return $count;
955 }
956
957 function get_question_comments_count( $userid ){
958 $count = WPF()->db->get_var("SELECT count(postid) FROM `".WPF()->tables->posts."` WHERE `parentid` > 0 AND `userid` = ".intval($userid));
959 return $count;
960 }
961
962 function get_replies_count( $userid ){
963 $count = WPF()->db->get_var("SELECT count(postid) FROM `".WPF()->tables->posts."` WHERE `userid` = ".intval($userid));
964 return $count;
965 }
966
967 function get_likes_count( $userid ){
968 $count = WPF()->db->get_var("SELECT count(likeid) FROM `".WPF()->tables->likes."` WHERE `userid` = ".intval($userid));
969 return $count;
970 }
971
972 function get_votes_count( $userid ){
973 $count = WPF()->db->get_var("SELECT count(voteid) FROM `".WPF()->tables->votes."` WHERE `userid` = ".intval($userid));
974 return $count;
975 }
976
977 // how many times the user like or vote
978 function get_votes_and_likes_count( $userid ){
979 return $this->get_votes_count( intval($userid) ) + $this->get_likes_count( intval($userid) );
980 }
981
982 //getting user's posts votes and likes count
983 function get_user_votes_and_likes_count( $userid ){
984 $votes_count = WPF()->db->get_var("SELECT count(voteid) FROM `".WPF()->tables->votes."` WHERE `post_userid` = ".intval($userid));
985 $likes_count = WPF()->db->get_var("SELECT count(likeid) FROM `".WPF()->tables->likes."` WHERE `post_userid` = ".intval($userid));
986 return $votes_count + $likes_count;
987 }
988
989 function get_profile_url( $arg, $template = 'profile' ){
990 if(!$arg) return wpforo_home_url();
991 $userid = intval( basename($arg) );
992 $member_args = ( $userid ? $userid : array( 'user_nicename' => basename($arg) ) );
993 $user = $this->get_member( $member_args );
994 if(empty($user)) return wpforo_home_url();
995 $user_slug = ( wpfo(WPF()->member->options['url_structure'], false) == 'id' ? $user['ID'] : $user['user_nicename'] );
996 $profile_url = wpforo_home_url("$template/$user_slug");
997 return apply_filters('wpforo_member_profile_url', $profile_url, $user, $template);
998 }
999
1000 function profile_url( $member = array(), $template = 'profile' ){
1001 if(isset($member['ID']) || isset($member['user_nicename'])){
1002 $user_slug = ( wpfo(WPF()->member->options['url_structure'], false) == 'id' ? $member['ID'] : $member['user_nicename'] );
1003 $profile_url = wpforo_home_url("$template/$user_slug");
1004 $profile_url = apply_filters( 'wpforo_profile_url', $profile_url, $member, $template );
1005 }
1006 else{
1007 $profile_url = wpforo_home_url();
1008 $profile_url = apply_filters( 'wpforo_no_profile_url', $profile_url, $template );
1009
1010 }
1011 return apply_filters('wpforo_member_profile_url', $profile_url, $member, $template);
1012 }
1013
1014 //$args = UserID or Member Object
1015 //$live_count = TRUE / FALSE
1016 function get_stat( $args = array(), $live_count = false, $cache = false ){
1017
1018 $cache = WPF()->cache->on('memory_cashe');
1019
1020 $stat = array( 'points' => 0,
1021 'rating' => 0,
1022 'rating_procent' => 0,
1023 'color' => $this->rating(0, 'color'),
1024 'badge' => $this->rating(0, 'icon'),
1025 'posts' => 0,
1026 'topics' => 0,
1027 'questions' => 0,
1028 'answers' => 0,
1029 'question_comments' => 0,
1030 'likes' => 0,
1031 'liked' => 0,
1032 'title' => $this->rating(0, 'title'));
1033
1034 $userid = ( isset($args['userid']) && $args['userid'] ) ? $args['userid'] : $args;
1035
1036 if( $cache && isset(self::$cache['stat'][$userid]) ){
1037 return self::$cache['stat'][$userid];
1038 }
1039
1040 if( is_array($args) && isset($args['userid']) ){
1041 $userid = $args['userid'];
1042 $stat['topics'] = (int)$this->get_topics_count( $userid );
1043 if(isset($args['questions'])) $stat['questions'] = intval($args['questions']);
1044 if(isset($args['answers'])) $stat['answers'] = intval($args['answers']);
1045 if(isset($args['posts'])) $stat['posts'] = intval($args['posts']);
1046 if(isset($args['comments'])) $stat['question_comments'] = intval($args['comments']);
1047 }
1048 elseif($userid = wpforo_bigintval($args)){
1049 $stat['topics'] = (int)$this->get_topics_count( $userid );
1050 if($live_count){
1051 if($questions = $this->get_questions_count( $userid )) $stat['questions'] = $questions;
1052 if($answers = $this->get_answers_count( $userid )) $stat['answers'] = $answers;
1053 if($posts = $this->get_replies_count( $userid )) $stat['posts'] = $posts;
1054 if($question_comments = $this->get_question_comments_count( $userid )) $stat['question_comments'] = $question_comments;
1055 }
1056 else{
1057 $profile = WPF()->db->get_var("SELECT `posts`, `questions`, `answers`, `comments` FROM `".WPF()->tables->profiles."` WHERE `userid` = ".intval($userid));
1058 if(isset($profile['questions'])) $stat['questions'] = intval($profile['questions']);
1059 if(isset($profile['answers'])) $stat['answers'] = intval($profile['answers']);
1060 if(isset($profile['posts'])) $stat['posts'] = intval($profile['posts']);
1061 if(isset($profile['comments'])) $stat['question_comments'] = intval($profile['comments']);
1062 }
1063 }
1064
1065 if( $userid ){
1066 if($likes = $this->get_votes_and_likes_count( $userid )) $stat['likes'] = $likes;
1067 if($liked = $this->get_user_votes_and_likes_count( $userid )) $stat['liked'] = $liked;
1068 if($stat['posts']) $stat['points'] = $stat['posts']; //TO-DO: Point counter function based on all stat values.
1069 if($stat['points']) $stat['rating'] = $this->rating_level($stat['points'], false);
1070 if($stat['rating']) {
1071 $stat['rating_procent'] = $stat['rating'] * 10;
1072 $stat['title'] = $this->rating(intval($stat['rating']), 'title');
1073 $stat['color'] = $this->rating(intval($stat['rating']), 'color');
1074 $stat['badge'] = $this->rating(intval($stat['rating']), 'icon');
1075 }
1076 }
1077
1078 if($cache && isset($userid)){
1079 return self::$cache['stat'][$userid] = $stat;
1080 }
1081 else{
1082 return $stat;
1083 }
1084 }
1085
1086 function get_count(){
1087 return WPF()->db->get_var( "SELECT COUNT(p.`userid`) FROM `".WPF()->tables->profiles."` p
1088 INNER JOIN `".WPF()->db->users."` u ON u.`ID` = p.`userid` WHERE p.`status` NOT LIKE 'trashed'" );
1089 }
1090
1091
1092 function is_online( $userid, $duration = NULL ){
1093
1094 $cache = WPF()->cache->on('memory_cashe');
1095
1096 if( $cache && isset(self::$cache['online'][$userid]) ){
1097 if(self::$cache['online'][$userid]['durration'] == $duration ){
1098 if(isset(self::$cache['online'][$userid]['status'])){
1099 return self::$cache['online'][$userid]['status'];
1100 }
1101 }
1102 }
1103 if(!$duration) $duration = WPF()->member->options['online_status_timeout'];
1104 $sql = "SELECT `online_time` FROM `".WPF()->tables->profiles."` WHERE `userid` = %d";
1105 $sql = WPF()->db->prepare($sql, $userid);
1106 $online_time = intval( WPF()->db->get_var($sql) );
1107 $current_time = current_time( 'timestamp', 1 );
1108 $online_duration = $current_time - $online_time;
1109 if( $online_duration < $duration ) {
1110 $status = true;
1111 }
1112 else{
1113 $status = false;
1114 }
1115 if( $cache ){
1116 self::$cache['online'][$userid]['durration'] = $duration;
1117 return self::$cache['online'][$userid]['status'] = $status;
1118 }
1119 else{
1120 return $status;
1121 }
1122 }
1123
1124 public function show_online_indicator($userid, $ico = TRUE){
1125 if( $this->is_online($userid)) : ?>
1126
1127 <?php if($ico) : ?>
1128 <i class="far fa-lightbulb wpfsx wpfcl-8" title="<?php wpforo_phrase('Online') ?>"></i>
1129 <?php else : wpforo_phrase('Online'); endif ?>
1130
1131 <?php else : ?>
1132
1133 <?php if($ico) : ?>
1134 <i class="far fa-lightbulb wpfsx wpfcl-0" title="<?php wpforo_phrase('Offline') ?>"></i>
1135 <?php else : wpforo_phrase('Offline'); endif ?>
1136
1137 <?php endif;
1138 }
1139
1140 function online_members_count( $duration = NULL ){
1141 if(!$duration) $duration = WPF()->member->options['online_status_timeout'];
1142 $current_time = current_time( 'timestamp', 1 );
1143 $online_timeframe = $current_time - $duration;
1144 return WPF()->db->get_var( "SELECT COUNT(*) FROM `".WPF()->tables->profiles."` WHERE `online_time` > " . intval($online_timeframe) );
1145
1146 }
1147
1148 function get_online_members( $count = 1, $duration = NULL ){
1149 if(!$duration) $duration = WPF()->member->options['online_status_timeout'];
1150 $current_time = current_time( 'timestamp', 1 );
1151 $online_timeframe = $current_time - $duration;
1152 $args = array(
1153 'online_time' => $online_timeframe, // $current_time - $duration
1154 'orderby' => 'userid', // forumid, order, parentid
1155 'row_count' => $count,
1156 'order' => 'ASC', // ASC DESC
1157 );
1158 return $this->get_members($args);
1159 }
1160
1161 function levels(){
1162 $levels = array( 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
1163 return $levels;
1164 }
1165
1166 function rating( $level = false, $var = false, $default = false ){
1167 $rating = array();
1168 $rating['color'] = array( 0 => '#d2d2d2', 1 => '#4dca5c', 2 => '#4dca5c', 3 => '#4dca5c', 4 => '#4dca5c', 5 => '#4dca5c', 6 => '#E5D600', 7 => '#E5D600', 8 => '#E5D600', 9 => '#FF812D', 10 => '#E04A47' );
1169 $rating['points'] = array( 0 => 0, 1 => 5, 2 => 20, 3 => 50, 4 => 100, 5 => 250, 6 => 500, 7 => 750, 8 => 1000, 9 => 2500, 10 => 5000 );
1170 $rating['title'] = array( 0 => 'New Member', 1 => 'Active Member', 2 => 'Eminent Member', 3 => 'Trusted Member', 4 => 'Estimable Member', 5 => 'Reputable Member', 6 => 'Honorable Member', 7 => 'Prominent Member', 8 => 'Noble Member', 9 => 'Famed Member', 10 => 'Illustrious Member' );
1171 $rating['icon'] = array( 0 => 'far fa-star-half', 1 => 'fas fa-star', 2 => 'fas fa-star', 3 => 'fas fa-star', 4 => 'fas fa-star', 5 => 'fas fa-star', 6 => 'fas fa-certificate', 7 => 'fas fa-certificate', 8 => 'fas fa-certificate', 9 => 'fas fa-shield-alt', 10 => 'fas fa-trophy' );
1172
1173 if(!empty(WPF()->member->options['rating'])){
1174
1175 if($level === false) return WPF()->member->options['rating'];
1176 if(!empty(WPF()->member->options['rating'][$level])){
1177
1178 if(!$var) return WPF()->member->options['rating'][$level];
1179 if(!empty(WPF()->member->options['rating'][$level][$var])){
1180
1181 if( $var == 'icon' && strpos( WPF()->member->options['rating'][$level][$var], ' ' ) === false ) return $rating[$var][$level];
1182
1183 return WPF()->member->options['rating'][$level][$var];
1184 }
1185 }
1186 }
1187 if( $level !== false && $var ) { return $rating[$var][$level]; }
1188 elseif( $level !== false && !$var ){ foreach( $rating as $variable => $values ){ $level_data[$variable] = $values[$level];} return $level_data; }
1189 elseif( $level === false && !$var ) return $rating;
1190 else return array();
1191 }
1192
1193 function rating_level($member_posts, $percent = TRUE){
1194 $bar = 0;
1195 if($member_posts < $this->rating(1, 'points')){$bar = 0;}
1196 elseif($member_posts < $this->rating(2, 'points')){$bar = 10;}
1197 elseif($member_posts < $this->rating(3, 'points')){$bar = 20;}
1198 elseif($member_posts < $this->rating(4, 'points')){$bar = 30;}
1199 elseif($member_posts < $this->rating(5, 'points')){$bar = 40;}
1200 elseif($member_posts < $this->rating(6, 'points')){$bar = 50;}
1201 elseif($member_posts < $this->rating(7, 'points')){$bar = 60;}
1202 elseif($member_posts < $this->rating(8, 'points')){$bar = 70;}
1203 elseif($member_posts < $this->rating(9, 'points')){$bar = 80;}
1204 elseif($member_posts < $this->rating(10, 'points')){$bar = 90;}
1205 else{$bar = 100;}
1206 if($percent){
1207 return $bar;
1208 }else{
1209 return floor($bar/10);
1210 }
1211 }
1212
1213 function rating_badge($level = 0, $view = 'short'){
1214
1215 $level = ( $level > 10 ) ? floor($level/10) : $level;
1216
1217 if($level == 0){
1218 return '<i class="'. $this->rating($level, 'icon') .'"></i>';
1219 }
1220 elseif($level > 0 && $level < 6){
1221 if( $view == 'full' ){
1222 return str_repeat(' <i class="'. $this->rating($level, 'icon') .'"></i> ', $level);
1223 }
1224 else{
1225 return '<span>' . esc_html($level) . '</span> <i class="'. $this->rating($level, 'icon') .'"></i>';
1226 }
1227 }
1228 elseif($level > 5 && $level < 9){
1229 if( $view == 'full' ){
1230 return str_repeat(' <i class="'. $this->rating($level, 'icon') .'"></i> ', ($level-5));
1231 }
1232 else{
1233 return '<span>' . esc_html($level-5) . '</span> <i class="'. $this->rating($level, 'icon') .'"></i>';
1234 }
1235 }
1236 elseif($level > 8){
1237 return '<i class="'. $this->rating($level, 'icon') .'"></i>';
1238 }
1239 else{
1240 return '';
1241 }
1242 }
1243
1244 public function reset($userid){
1245 if( !$userid ) return;
1246 WPF()->db->query( "DELETE FROM `".WPF()->db->usermeta."` WHERE `meta_key` = '_wpf_member_obj' AND `user_id` = " . intval($userid) );
1247 wpforo_clean_cache( 'user', $userid );
1248 }
1249
1250 public function clear_db_cache(){
1251 WPF()->db->query( "DELETE FROM `".WPF()->db->usermeta."` WHERE `meta_key` = '_wpf_member_obj'" );
1252 }
1253
1254 private function update_online_time($userid = NULL){
1255 if(!$userid) $userid = WPF()->current_userid;
1256 if(!$userid) return false;
1257 $current_timestamp = current_time( 'timestamp', 1 );
1258 $sql = "UPDATE `".WPF()->tables->profiles."` SET `online_time` = %d WHERE `userid` = %d";
1259 $sql = WPF()->db->prepare($sql, $current_timestamp, wpforo_bigintval($userid));
1260 if( false !== WPF()->db->query($sql) ) return $current_timestamp;
1261 return false;
1262 }
1263
1264 public function init_current_user(){
1265 $current_user = wp_get_current_user();
1266 if( $current_user->exists() ){
1267 $user = $this->get_member( $current_user->ID );
1268 $status = ( isset($user['status']) ? $user['status'] : '' );
1269 if( $status == 'active' ){
1270 $user['groupid'] = intval($user['groupid']);
1271 WPF()->current_user = $user;
1272 WPF()->current_user_groupid = WPF()->current_user['groupid'];
1273 WPF()->current_userid = $current_user->ID;
1274 WPF()->current_username = $current_user->user_login;
1275 WPF()->current_user_email = $current_user->user_email;
1276 WPF()->current_user_display_name = $current_user->display_name;
1277
1278 $this->update_online_time();
1279 }
1280 WPF()->current_user_status = $status;
1281 }elseif ( $guest = $this->get_guest_cookies() ){
1282 WPF()->current_user = $this->get_guest($guest);
1283 WPF()->current_user_email = $guest['email'];
1284 WPF()->current_user_display_name = $guest['name'];
1285 }
1286 }
1287
1288 public function blog_posts( $userid ){
1289 if( isset($userid) && $userid ) return count_user_posts( $userid , 'post' );
1290 return 0;
1291 }
1292
1293 public function blog_comments($userid, $user_email){
1294 global $wpdb;
1295 if( !$userid || !$user_email ) return 0;
1296 return (int) $wpdb->get_var("SELECT COUNT(*) FROM " . $wpdb->comments. " WHERE `user_id` = " . intval($userid) . " OR `comment_author_email` = '" . esc_sql($user_email) . "'");
1297 }
1298
1299 public function show_delete_form($current_user, $userids){
1300 if( empty($current_user) || empty($userids) ) return;
1301
1302 $userids = array_diff( $userids, array( $current_user->ID ) );
1303 $users_have_content = false;
1304 if ( WPF()->db->get_var( "SELECT `postid` FROM `".WPF()->tables->posts."` WHERE `userid` IN( " . implode( ',', array_map('intval', $userids) ) . " ) LIMIT 1" ) ) {
1305 $users_have_content = true;
1306 }
1307 ?>
1308 <hr /><strong>#wpForo</strong>
1309 <?php if ( ! $users_have_content ) : ?>
1310 <input type="hidden" name="wpforo_user_delete_option" value="delete" />
1311 <?php else: ?>
1312 <?php if ( 1 == count($userids) ) : ?>
1313 <fieldset><p><legend><?php _e( 'What should be done with wpForo content owned by this user?', 'wpforo' ); ?></legend></p>
1314 <?php else : ?>
1315 <fieldset><p><legend><?php _e( 'What should be done with wpForo content owned by these users?', 'wpforo' ); ?></legend></p>
1316 <?php endif; ?>
1317 <ul style="list-style:none;">
1318 <li><label><input type="radio" id="wpforo_delete_option0" name="wpforo_user_delete_option" value="delete" />
1319 <?php _e('Delete all wpForo content.', 'wpforo'); ?></label></li>
1320 <li><input type="radio" id="wpforo_delete_option1" name="wpforo_user_delete_option" value="reassign" />
1321 <?php echo '<label for="wpforo_delete_option1">' . __( 'Attribute all content to:' ) . '</label> ';
1322 wp_dropdown_users( array(
1323 'name' => 'wpforo_reassign_user',
1324 'exclude' => $userids,
1325 'show' => 'display_name_with_login',
1326 ) ); ?></li>
1327 </ul></fieldset>
1328 <script type="text/javascript">
1329 jQuery(document).ready( function($) {
1330 $('#wpforo_reassign_user').focus( function() {
1331 $('#wpforo_delete_option1').prop('checked', true).trigger('change');
1332 });
1333 });
1334 </script>
1335 <?php endif;
1336 }
1337
1338
1339
1340 public function autoban($userid){
1341 if( !WPF()->perm->usergroup_can( 'em' ) ){
1342 WPF()->db->update(
1343 WPF()->tables->profiles,
1344 array('status' => 'banned'),
1345 array('userid' => intval( $userid )),
1346 array('%s'),
1347 array('%d')
1348 );
1349 }
1350 }
1351
1352 public function member_approved_posts( $member = array() ){
1353 if(is_numeric($member)){
1354 if( isset(WPF()->current_user['posts']) && WPF()->current_user['posts'] && $member == WPF()->current_userid ){
1355 return WPF()->current_user['posts'];
1356 }
1357 elseif($member){
1358 return WPF()->db->get_var( "SELECT COUNT(*) as posts FROM `".WPF()->tables->posts."` WHERE `status` = 0 AND `userid` = " . intval($member) );
1359 }
1360 else{
1361 return 0;
1362 }
1363 }
1364 elseif(is_array($member) && !empty($member)){
1365 return intval($member['posts']);
1366 }
1367 else{
1368 return 0;
1369 }
1370 }
1371
1372 public function current_user_is_new(){
1373 if( WPF()->perm->usergroup_can( 'em' ) ){
1374 //This is an admin or moderator. The number of posts doesn't matter.
1375 return false;
1376 }
1377 else{
1378 $posts = $this->member_approved_posts( WPF()->current_userid );
1379 if ( $posts < WPF()->tools_antispam['new_user_max_posts'] ) {
1380 return true;
1381 }
1382 else{
1383 return false;
1384 }
1385 }
1386 }
1387
1388 public function banned_count(){
1389 $count = WPF()->db->get_var("SELECT count(*) FROM `".WPF()->tables->profiles."` WHERE `status` = 'banned' " );
1390 return $count;
1391 }
1392
1393 public function get_guest( $args = array() ){
1394
1395 $cache = WPF()->cache->on('memory_cashe');
1396
1397 if( !isset($args['name']) || $args['name'] == '' ) $args['name'] = wpforo_phrase('Anonymous', false);
1398 if( !isset($args['email']) || $args['email'] == '' ) $args['email'] = 'anonymous@example.com';
1399
1400 $args['name'] = strip_tags($args['name']);
1401 $args['email'] = strip_tags($args['email']);
1402 $args['posts'] = 0;
1403 $args['user_registered'] = 0;
1404
1405 if(isset($args['email'])){
1406 if( $cache && isset(self::$cache['guest'][$args['email']]) ){
1407 return self::$cache['guest'][$args['email']];
1408 }
1409 }
1410
1411 if( $args['email'] ){
1412 $post_args = array( 'email' => $args['email'], 'orderby' => '`created` ASC, `postid` ASC' );
1413 $posts = WPF()->post->get_posts( $post_args );
1414 if( !empty($posts) ){
1415 $args['posts'] = count($posts);
1416 if( isset($posts[0]['created']) || $posts[0]['created'] ) $args['user_registered'] = $posts[0]['created'];
1417 }
1418 }
1419
1420 $member = array( 'ID' => 0,
1421 'userid' => 0,
1422 'user_login' => $args['name'],
1423 'user_pass' => '',
1424 'user_nicename' => sanitize_text_field($args['name']),
1425 'user_email' => $args['email'],
1426 'user_url' => '',
1427 'user_registered' => $args['user_registered'],
1428 'user_activation_key' => '',
1429 'user_status' => 0,
1430 'display_name' => $args['name'],
1431 'title' => '',
1432 'username' => $args['name'],
1433 'groupid' => 4,
1434 'posts' => $args['posts'], 'questions' => 0, 'answers' => 0, 'comments' => 0, 'site' => '', 'icq' => '', 'aim' => '', 'yahoo' => '', 'msn' => '', 'facebook' => '', 'twitter' => '', 'gtalk' => '', 'skype' => '', 'avatar' => '', 'signature' => '', 'about' => '', 'occupation' => '', 'location' => '', 'last_login' => '', 'rank' => 0, 'like' => 0,
1435 'status' => 'active',
1436 'timezone' => '',
1437 'name' => $args['name'],
1438 'cans' => '',
1439 'description' => '',
1440 'groupname' => wpforo_phrase('Guest', false),
1441 'profile_url' => '',
1442 'stat' => array( 'points' => 0, 'rating' => 0, 'rating_procent' => 0, 'color' => '', 'badge' => '', 'posts' => $args['posts'], 'topics' => 0, 'questions' => 0, 'answers' => 0, 'question_comments' => 0, 'likes' => 0, 'liked' => 0, 'title' => '' ),
1443 'is_email_confirmed' => 0
1444 );
1445
1446 if( $cache && $args['email'] ){
1447 return self::$cache['guest'][$args['email']] = $member;
1448 }else{
1449 return $member;
1450 }
1451
1452 }
1453
1454 public function init_fields(){
1455 if( !empty($this->fields) ) return;
1456
1457 $this->init_countries();
1458 $this->init_timezones();
1459
1460 $this->fields = apply_filters('wpforo_member_before_init_fields', $this->fields);
1461
1462 $usergroupids = WPF()->usergroup->get_usergroups('groupid');
1463 $usergroupids_can_edit_fields = WPF()->perm->usergroups_can('em');
1464 $usergroupids_can_view_social_net = WPF()->perm->usergroups_can('vmsn');
1465
1466 $this->fields['user_login'] = array(
1467 'fieldKey' => 'user_login',
1468 'type' => 'text',
1469 'isDefault' => 1,
1470 'isRemovable' => 0,
1471 'isRequired' => 1,
1472 'isEditable' => 0,
1473 'label' => wpforo_phrase('Username', false),
1474 'title' => wpforo_phrase('Username', false),
1475 'placeholder' => wpforo_phrase('Username', false),
1476 'description' => wpforo_phrase('Length must be between 3 characters and 15 characters.', false),
1477 'minLength' => $this->default->login_min_length,
1478 'maxLength' => $this->default->login_max_length,
1479 'faIcon' => 'fas fa-user',
1480 'name' => 'user_login',
1481 'canBeInactive' => array(
1482 'account',
1483 'profile',
1484 'search'
1485 ),
1486 'canEdit' => array(),
1487 'canView' => WPF()->perm->usergroups_can('vmu'),
1488 'can' => 'vmu',
1489 'isSearchable' => 0
1490 );
1491
1492 $this->fields['user_email'] = array(
1493 'fieldKey' => 'user_email',
1494 'type' => 'email',
1495 'isDefault' => 1,
1496 'isRemovable' => 0,
1497 'isRequired' => 1,
1498 'isEditable' => 1,
1499 'label' => wpforo_phrase('Email', false),
1500 'title' => wpforo_phrase('Email', false),
1501 'placeholder' => wpforo_phrase('Email', false),
1502 'minLength' => 0,
1503 'maxLength' => 0,
1504 'faIcon' => 'fas fa-envelope',
1505 'name' => 'user_email',
1506 'canBeInactive' => array(
1507 'account',
1508 'profile',
1509 'search'
1510 ),
1511 'canEdit' => $usergroupids_can_edit_fields,
1512 'canView' => WPF()->perm->usergroups_can('vmm'),
1513 'can' => 'vmm',
1514 'isSearchable' => 1
1515 );
1516
1517 $this->fields['user_pass'] = array(
1518 'fieldKey' => 'user_pass',
1519 'type' => 'password',
1520 'isDefault' => 1,
1521 'isRemovable' => 0,
1522 'isRequired' => 1,
1523 'isEditable' => 1,
1524 'isConfirmPassword' => 1,
1525 'label' => wpforo_phrase('Password', false),
1526 'title' => wpforo_phrase('Password', false),
1527 'placeholder' => wpforo_phrase('Password', false),
1528 'description' => wpforo_phrase('Must be minimum 6 characters.', false),
1529 'minLength' => $this->default->pass_min_length,
1530 'maxLength' => $this->default->pass_max_length,
1531 'faIcon' => 'fas fa-key',
1532 'name' => 'user_pass',
1533 'canBeInactive' => array(
1534 'profile',
1535 'search'
1536 ),
1537 'canEdit' => $usergroupids_can_edit_fields,
1538 'canView' => array(),
1539 'can' => '',
1540 'isSearchable' => 0
1541 );
1542
1543 $this->fields['display_name'] = array(
1544 'fieldKey' => 'display_name',
1545 'type' => 'text',
1546 'isDefault' => 1,
1547 'isRemovable' => 0,
1548 'isRequired' => 1,
1549 'isEditable' => 1,
1550 'label' => wpforo_phrase('Display Name', false),
1551 'title' => wpforo_phrase('Display Name', false),
1552 'placeholder' => wpforo_phrase('Display Name', false),
1553 'faIcon' => 'fas fa-user',
1554 'name' => 'display_name',
1555 'canBeInactive' => array(
1556 'profile',
1557 'search'
1558 ),
1559 'canEdit' => $usergroupids_can_edit_fields,
1560 'canView' => $usergroupids,
1561 'can' => '',
1562 'isSearchable' => 1
1563 );
1564
1565 $this->fields['user_nicename'] = array(
1566 'fieldKey' => 'user_nicename',
1567 'type' => 'text',
1568 'isDefault' => 1,
1569 'isRemovable' => 0,
1570 'isRequired' => 1,
1571 'isEditable' => 1,
1572 'label' => wpforo_phrase('Nickname', false),
1573 'title' => wpforo_phrase('Nickname', false),
1574 'placeholder' => wpforo_phrase('Nickname', false),
1575 'description' => wpforo_phrase('URL Address Identifier', false),
1576 'minLength' => 0,
1577 'maxLength' => 0,
1578 'faIcon' => 'fas fa-link',
1579 'name' => 'user_nicename',
1580 'canBeInactive' => array(
1581 'register',
1582 'account',
1583 'profile',
1584 'search'
1585 ),
1586 'canEdit' => $usergroupids_can_edit_fields,
1587 'canView' => $usergroupids,
1588 'can' => '',
1589 'isSearchable' => 1
1590 );
1591
1592 $this->fields['title'] = array(
1593 'fieldKey' => 'title',
1594 'type' => 'text',
1595 'isDefault' => 1,
1596 'isRemovable' => 0,
1597 'isRequired' => 1,
1598 'isEditable' => 1,
1599 'label' => wpforo_phrase('Title', false),
1600 'title' => wpforo_phrase('Title', false),
1601 'placeholder' => wpforo_phrase('Title', false),
1602 'minLength' => 0,
1603 'maxLength' => 0,
1604 'faIcon' => 'fas fa-user',
1605 'name' => 'title',
1606 'canBeInactive' => array(
1607 'register',
1608 'account',
1609 'profile',
1610 'search'
1611 ),
1612 'canEdit' => $usergroupids_can_edit_fields,
1613 'canView' => WPF()->perm->usergroups_can('vmt'),
1614 'can' => 'vmt',
1615 'isSearchable' => 1
1616 );
1617
1618 $this->fields['groupid'] = array(
1619 'fieldKey' => 'groupid',
1620 'type' => 'usergroup',
1621 'isDefault' => 1,
1622 'isRemovable' => 0,
1623 'isRequired' => 1,
1624 'isEditable' => 1,
1625 'label' => wpforo_phrase('User Group', false),
1626 'title' => wpforo_phrase('User Group', false),
1627 'placeholder' => wpforo_phrase('User Group', false),
1628 'faIcon' => 'fas fa-users',
1629 'name' => 'groupid',
1630 'allowedGroupIds' => array(),
1631 'canBeInactive' => array(
1632 'register',
1633 'account',
1634 'profile',
1635 'search'
1636 ),
1637 'canEdit' => $usergroupids_can_edit_fields,
1638 'canView' => $usergroupids,
1639 'can' => '',
1640 'isSearchable' => 1
1641 );
1642
1643 $this->fields['avatar'] = array(
1644 'fieldKey' => 'avatar',
1645 'type' => 'avatar',
1646 'isDefault' => 1,
1647 'isRemovable' => 0,
1648 'isRequired' => 0,
1649 'isEditable' => 1,
1650 'label' => wpforo_phrase('Avatar', false),
1651 'title' => wpforo_phrase('Avatar', false),
1652 'placeholder' => wpforo_phrase('Avatar', false),
1653 'name' => 'avatar',
1654 'canBeInactive' => array(
1655 'register',
1656 'account',
1657 'profile',
1658 'search'
1659 ),
1660 'canEdit' => $usergroupids_can_edit_fields,
1661 'canView' => WPF()->perm->usergroups_can('va'),
1662 'can' => 'va',
1663 'isSearchable' => 0
1664 );
1665
1666 $this->fields['site'] = array(
1667 'fieldKey' => 'site',
1668 'type' => 'url',
1669 'isDefault' => 1,
1670 'isRemovable' => 0,
1671 'isRequired' => 0,
1672 'isEditable' => 1,
1673 'label' => wpforo_phrase('Website', false),
1674 'title' => wpforo_phrase('Website', false),
1675 'placeholder' => wpforo_phrase('Website', false),
1676 'faIcon' => 'fas fa-sitemap',
1677 'name' => 'site',
1678 'canBeInactive' => array(
1679 'register',
1680 'account',
1681 'profile',
1682 'search'
1683 ),
1684 'canEdit' => $usergroupids_can_edit_fields,
1685 'canView' => WPF()->perm->usergroups_can('vmw'),
1686 'can' => 'vmw',
1687 'isSearchable' => 1
1688 );
1689
1690 $this->fields['facebook'] = array(
1691 'fieldKey' => 'facebook',
1692 'type' => 'url',
1693 'isDefault' => 1,
1694 'isRemovable' => 0,
1695 'isRequired' => 0,
1696 'isEditable' => 1,
1697 'label' => wpforo_phrase('Facebook', false),
1698 'title' => wpforo_phrase('Facebook', false),
1699 'placeholder' => wpforo_phrase('Facebook', false),
1700 'faIcon' => 'fab fa-facebook',
1701 'name' => 'facebook',
1702 'canBeInactive' => array(
1703 'register',
1704 'account',
1705 'profile',
1706 'search'
1707 ),
1708 'canEdit' => $usergroupids_can_edit_fields,
1709 'canView' => $usergroupids_can_view_social_net,
1710 'can' => 'vmsn',
1711 'isSearchable' => 1
1712 );
1713
1714 $this->fields['twitter'] = array(
1715 'fieldKey' => 'twitter',
1716 'type' => 'url',
1717 'isDefault' => 1,
1718 'isRemovable' => 0,
1719 'isRequired' => 0,
1720 'isEditable' => 1,
1721 'label' => wpforo_phrase('Twitter', false),
1722 'title' => wpforo_phrase('Twitter', false),
1723 'placeholder' => wpforo_phrase('Twitter', false),
1724 'faIcon' => 'fab fa-twitter-square',
1725 'name' => 'twitter',
1726 'canBeInactive' => array(
1727 'register',
1728 'account',
1729 'profile',
1730 'search'
1731 ),
1732 'canEdit' => $usergroupids_can_edit_fields,
1733 'canView' => $usergroupids_can_view_social_net,
1734 'can' => 'vmsn',
1735 'isSearchable' => 1
1736 );
1737
1738 $this->fields['gtalk'] = array(
1739 'fieldKey' => 'gtalk',
1740 'type' => 'url',
1741 'isDefault' => 1,
1742 'isRemovable' => 0,
1743 'isRequired' => 0,
1744 'isEditable' => 1,
1745 'label' => wpforo_phrase('Google+', false),
1746 'title' => wpforo_phrase('Google+', false),
1747 'placeholder' => wpforo_phrase('Google+', false),
1748 'faIcon' => 'fab fa-google-plus-square',
1749 'name' => 'gtalk',
1750 'canBeInactive' => array(
1751 'register',
1752 'account',
1753 'profile',
1754 'search'
1755 ),
1756 'canEdit' => $usergroupids_can_edit_fields,
1757 'canView' => $usergroupids_can_view_social_net,
1758 'can' => 'vmsn',
1759 'isSearchable' => 1
1760 );
1761
1762 $this->fields['yahoo'] = array(
1763 'fieldKey' => 'yahoo',
1764 'type' => 'text',
1765 'isDefault' => 1,
1766 'isRemovable' => 0,
1767 'isRequired' => 0,
1768 'isEditable' => 1,
1769 'label' => wpforo_phrase('Yahoo', false),
1770 'title' => wpforo_phrase('Yahoo', false),
1771 'placeholder' => wpforo_phrase('Yahoo', false),
1772 'faIcon' => 'fab fa-yahoo',
1773 'name' => 'yahoo',
1774 'canBeInactive' => array(
1775 'register',
1776 'account',
1777 'profile',
1778 'search'
1779 ),
1780 'canEdit' => $usergroupids_can_edit_fields,
1781 'canView' => $usergroupids_can_view_social_net,
1782 'can' => 'vmsn',
1783 'isSearchable' => 1
1784 );
1785
1786 $this->fields['aim']= array(
1787 'fieldKey' => 'aim',
1788 'type' => 'text',
1789 'isDefault' => 1,
1790 'isRemovable' => 0,
1791 'isRequired' => 0,
1792 'isEditable' => 1,
1793 'label' => wpforo_phrase('AOL IM', false),
1794 'title' => wpforo_phrase('AOL IM', false),
1795 'placeholder' => wpforo_phrase('AOL IM', false),
1796 'faIcon' => 'fas fa-share-alt',
1797 'name' => 'aim',
1798 'canBeInactive' => array(
1799 'register',
1800 'account',
1801 'profile',
1802 'search'
1803 ),
1804 'canEdit' => $usergroupids_can_edit_fields,
1805 'canView' => $usergroupids_can_view_social_net,
1806 'can' => 'vmsn',
1807 'isSearchable' => 1
1808 );
1809
1810 $this->fields['icq'] = array(
1811 'fieldKey' => 'icq',
1812 'type' => 'text',
1813 'isDefault' => 1,
1814 'isRemovable' => 0,
1815 'isRequired' => 0,
1816 'isEditable' => 1,
1817 'label' => wpforo_phrase('ICQ', false),
1818 'title' => wpforo_phrase('ICQ', false),
1819 'placeholder' => wpforo_phrase('ICQ', false),
1820 'faIcon' => 'fas fa-share-alt',
1821 'name' => 'icq',
1822 'canBeInactive' => array(
1823 'register',
1824 'account',
1825 'profile',
1826 'search'
1827 ),
1828 'canEdit' => $usergroupids_can_edit_fields,
1829 'canView' => $usergroupids_can_view_social_net,
1830 'can' => 'vmsn',
1831 'isSearchable' => 1
1832 );
1833
1834 $this->fields['msn'] = array(
1835 'fieldKey' => 'msn',
1836 'type' => 'text',
1837 'isDefault' => 1,
1838 'isRemovable' => 0,
1839 'isRequired' => 0,
1840 'isEditable' => 1,
1841 'label' => wpforo_phrase('MSN', false),
1842 'title' => wpforo_phrase('MSN', false),
1843 'placeholder' => wpforo_phrase('MSN', false),
1844 'faIcon' => 'fas fa-share-alt',
1845 'name' => 'msn',
1846 'canBeInactive' => array(
1847 'register',
1848 'account',
1849 'profile',
1850 'search'
1851 ),
1852 'canEdit' => $usergroupids_can_edit_fields,
1853 'canView' => $usergroupids_can_view_social_net,
1854 'can' => 'vmsn',
1855 'isSearchable' => 1
1856 );
1857
1858 $this->fields['skype'] = array(
1859 'fieldKey' => 'skype',
1860 'type' => 'text',
1861 'isDefault' => 1,
1862 'isRemovable' => 0,
1863 'isRequired' => 0,
1864 'isEditable' => 1,
1865 'label' => wpforo_phrase('Skype', false),
1866 'title' => wpforo_phrase('Skype', false),
1867 'placeholder' => wpforo_phrase('Skype', false),
1868 'faIcon' => 'fab fa-skype',
1869 'name' => 'skype',
1870 'canBeInactive' => array(
1871 'register',
1872 'account',
1873 'profile',
1874 'search'
1875 ),
1876 'canEdit' => $usergroupids_can_edit_fields,
1877 'canView' => $usergroupids_can_view_social_net,
1878 'can' => 'vmsn',
1879 'isSearchable' => 1
1880 );
1881
1882 $this->fields['location'] = array(
1883 'fieldKey' => 'location',
1884 'type' => 'select',
1885 'isDefault' => 1,
1886 'isRemovable' => 0,
1887 'isRequired' => 0,
1888 'isEditable' => 1,
1889 'label' => wpforo_phrase('Location', false),
1890 'title' => wpforo_phrase('Location', false),
1891 'placeholder' => wpforo_phrase('Location', false),
1892 'faIcon' => 'fas fa-globe',
1893 'values' => $this->countries,
1894 'name' => 'location',
1895 'canBeInactive' => array(
1896 'register',
1897 'account',
1898 'profile',
1899 'search'
1900 ),
1901 'canEdit' => $usergroupids_can_edit_fields,
1902 'canView' => WPF()->perm->usergroups_can('vml'),
1903 'can' => 'vml',
1904 'isSearchable' => 1
1905 );
1906
1907 $this->fields['timezone'] = array(
1908 'fieldKey' => 'timezone',
1909 'type' => 'select',
1910 'isDefault' => 1,
1911 'isRemovable' => 0,
1912 'isRequired' => 0,
1913 'isEditable' => 1,
1914 'label' => wpforo_phrase('Timezone', false),
1915 'title' => wpforo_phrase('Timezone', false),
1916 'placeholder' => wpforo_phrase('Timezone', false),
1917 'faIcon' => 'fas fa-globe',
1918 'values' => $this->timezones,
1919 'name' => 'timezone',
1920 'canBeInactive' => array(
1921 'register',
1922 'account',
1923 'profile',
1924 'search'
1925 ),
1926 'canEdit' => $usergroupids_can_edit_fields,
1927 'canView' => $usergroupids,
1928 'can' => '',
1929 'isSearchable' => 1
1930 );
1931
1932 $this->fields['occupation'] = array(
1933 'fieldKey' => 'occupation',
1934 'type' => 'text',
1935 'isDefault' => 1,
1936 'isRemovable' => 0,
1937 'isRequired' => 0,
1938 'isEditable' => 1,
1939 'label' => wpforo_phrase('Occupation', false),
1940 'title' => wpforo_phrase('Occupation', false),
1941 'placeholder' => wpforo_phrase('Occupation', false),
1942 'faIcon' => 'fas fa-address-card',
1943 'name' => 'occupation',
1944 'canBeInactive' => array(
1945 'register',
1946 'account',
1947 'profile',
1948 'search'
1949 ),
1950 'canEdit' => $usergroupids_can_edit_fields,
1951 'canView' => WPF()->perm->usergroups_can('vmo'),
1952 'can' => 'vmo',
1953 'isSearchable' => 1
1954 );
1955
1956 $this->fields['signature'] = array(
1957 'fieldKey' => 'signature',
1958 'type' => 'textarea',
1959 'isDefault' => 1,
1960 'isRemovable' => 0,
1961 'isRequired' => 0,
1962 'isEditable' => 1,
1963 'label' => wpforo_phrase('Signature', false),
1964 'title' => wpforo_phrase('Signature', false),
1965 'placeholder' => wpforo_phrase('Signature', false),
1966 'faIcon' => 'fas fa-address-card',
1967 'name' => 'signature',
1968 'canBeInactive' => array(
1969 'register',
1970 'account',
1971 'profile',
1972 'search'
1973 ),
1974 'canEdit' => $usergroupids_can_edit_fields,
1975 'canView' => WPF()->perm->usergroups_can('vms'),
1976 'can' => 'vms',
1977 'isSearchable' => 1
1978 );
1979
1980 $this->fields['about'] = array(
1981 'fieldKey' => 'about',
1982 'type' => 'textarea',
1983 'isDefault' => 1,
1984 'isRemovable' => 0,
1985 'isRequired' => 0,
1986 'isEditable' => 1,
1987 'label' => wpforo_phrase('About Me', false),
1988 'title' => wpforo_phrase('About Me', false),
1989 'placeholder' => wpforo_phrase('About Me', false),
1990 'faIcon' => 'fas fa-address-card',
1991 'name' => 'about',
1992 'canBeInactive' => array(
1993 'register',
1994 'account',
1995 'profile',
1996 'search'
1997 ),
1998 'canEdit' => $usergroupids_can_edit_fields,
1999 'canView' => WPF()->perm->usergroups_can('vmam'),
2000 'can' => 'vmam',
2001 'isSearchable' => 1
2002 );
2003
2004 $this->fields['html_soc_net'] = array(
2005 'fieldKey' => 'html_soc_net',
2006 'type' => 'html',
2007 'isDefault' => 1,
2008 'isRemovable' => 0,
2009 'isRequired' => 0,
2010 'isEditable' => 1,
2011 'label' => wpforo_phrase('Social Networks', false),
2012 'title' => wpforo_phrase('Social Networks', false),
2013 'placeholder' => wpforo_phrase('Social Networks', false),
2014 'description' => wpforo_phrase('Social Networks', false),
2015 'html' => '<div class="wpf-label">' . wpforo_phrase('Social Networks', false) . '</div>',
2016 'name' => 'html_soc_net',
2017 'canBeInactive' => array(
2018 'register',
2019 'account',
2020 'profile',
2021 'search'
2022 ),
2023 'canEdit' => $usergroupids_can_edit_fields,
2024 'canView' => $usergroupids_can_view_social_net,
2025 'can' => 'vmsn',
2026 'isSearchable' => 0
2027 );
2028
2029 $this->fields = apply_filters('wpforo_member_after_init_fields', $this->fields);
2030 }
2031
2032 private function init_countries(){
2033 $this->countries = array( "Afghanistan","�
2034 land Islands","Albania","Algeria","American Samoa","Andorra","Angola","Anguilla","Antarctica",
2035 "Antigua and Barbuda","Argentina","Armenia","Aruba","Australia","Austria","Azerbaijan","Bahamas","Bahrain",
2036 "Bangladesh","Barbados","Belarus","Belgium","Belize","Benin","Bermuda","Bhutan","Bolivia","Bosnia and Herzegovina",
2037 "Botswana","Bouvet Island","Brazil","British Indian Ocean Territory","Brunei Darussalam","Bulgaria","Burkina Faso",
2038 "Burundi","Cambodia","Cameroon","Canada","Cape Verde","Cayman Islands","Central African Republic","Chad","Chile",
2039 "China","Christmas Island","Cocos (Keeling) Islands","Colombia","Comoros","Congo","Congo, The Democratic Republic of The",
2040 "Cook Islands","Costa Rica","Cote D'ivoire","Croatia","Cuba","Cyprus","Czech Republic","Denmark","Djibouti","Dominica",
2041 "Dominican Republic","Ecuador","Egypt","El Salvador","Equatorial Guinea","Eritrea","Estonia","Ethiopia","Falkland Islands (Malvinas)",
2042 "Faroe Islands","Fiji","Finland","France","French Guiana","French Polynesia","French Southern Territories","Gabon",
2043 "Gambia","Georgia","Germany","Ghana","Gibraltar","Greece","Greenland","Grenada","Guadeloupe","Guam","Guatemala",
2044 "Guernsey","Guinea","Guinea-bissau","Guyana","Haiti","Heard Island and Mcdonald Islands","Holy See (Vatican City State)",
2045 "Honduras","Hong Kong","Hungary","Iceland","India","Indonesia","Iran, Islamic Republic of","Iraq","Ireland",
2046 "Isle of Man","Israel","Italy","Jamaica","Japan","Jersey","Jordan","Kazakhstan","Kenya","Kiribati","Korea, Democratic People's Republic of",
2047 "Korea, Republic of","Kuwait","Kyrgyzstan","Lao People's Democratic Republic","Latvia","Lebanon","Lesotho","Liberia",
2048 "Libyan Arab Jamahiriya","Liechtenstein","Lithuania","Luxembourg","Macao","Macedonia, The Former Yugoslav Republic of",
2049 "Madagascar","Malawi","Malaysia","Maldives","Mali","Malta","Marshall Islands","Martinique","Mauritania","Mauritius",
2050 "Mayotte","Mexico","Micronesia, Federated States of","Moldova, Republic of","Monaco","Mongolia","Montenegro","Montserrat",
2051 "Morocco","Mozambique","Myanmar","Namibia","Nauru","Nepal","Netherlands","Netherlands Antilles","New Caledonia",
2052 "New Zealand","Nicaragua","Niger","Nigeria","Niue","Norfolk Island","Northern Mariana Islands","Norway","Oman",
2053 "Pakistan","Palau","Palestinian Territory, Occupied","Panama","Papua New Guinea","Paraguay","Peru","Philippines",
2054 "Pitcairn","Poland","Portugal","Puerto Rico","Qatar","Reunion","Romania","Russian Federation","Rwanda","Saint Helena",
2055 "Saint Kitts and Nevis","Saint Lucia","Saint Pierre and Miquelon","Saint Vincent and The Grenadines","Samoa",
2056 "San Marino","Sao Tome and Principe","Saudi Arabia","Senegal","Serbia","Seychelles","Sierra Leone","Singapore",
2057 "Slovakia","Slovenia","Solomon Islands","Somalia","South Africa","South Georgia and The South Sandwich Islands",
2058 "Spain","Sri Lanka","Sudan","Suriname","Svalbard and Jan Mayen","Swaziland","Sweden","Switzerland","Syrian Arab Republic",
2059 "Taiwan, Province of China","Tajikistan","Tanzania, United Republic of","Thailand","Timor-leste","Togo","Tokelau",
2060 "Tonga","Trinidad and Tobago","Tunisia","Turkey","Turkmenistan","Turks and Caicos Islands","Tuvalu","Uganda","Ukraine",
2061 "United Arab Emirates","United Kingdom","United States","United States Minor Outlying Islands","Uruguay","Uzbekistan",
2062 "Vanuatu","Venezuela","Viet Nam","Virgin Islands, British","Virgin Islands, U.S.","Wallis and Futuna","Western Sahara",
2063 "Yemen","Zambia","Zimbabwe" );
2064 }
2065
2066 private function init_timezones(){
2067 $this->timezones = timezone_identifiers_list();
2068 $offset_range = array (-12, -11.5, -11, -10.5, -10, -9.5, -9, -8.5, -8, -7.5, -7, -6.5, -6, -5.5, -5, -4.5, -4, -3.5, -3, -2.5, -2, -1.5, -1, -0.5,
2069 0, 0.5, 1, 1.5, 2, 2.5, 3, 3.5, 4, 4.5, 5, 5.5, 5.75, 6, 6.5, 7, 7.5, 8, 8.5, 8.75, 9, 9.5, 10, 10.5, 11, 11.5, 12, 12.75, 13, 13.75, 14);
2070 foreach ( $offset_range as $offset ) {
2071 if ( 0 <= $offset )
2072 $offset_name = '+' . $offset;
2073 else
2074 $offset_name = (string) $offset;
2075
2076 $offset_value = $offset_name;
2077 $offset_value = 'UTC' . $offset_value;
2078 $this->timezones[] = 'UTC/' . $offset_value;
2079 }
2080
2081 $zones = $this->timezones;
2082 $timezones = array();
2083 foreach($zones as $zone){
2084 if(strpos($zone, '/') === false) continue;
2085
2086 $zone = str_replace('_', ' ', $zone);
2087
2088 $group = function_exists('mb_substr') ? mb_substr($zone, 0, strpos($zone, '/')) : substr($zone, 0, strpos($zone, '/'));
2089 $index = function_exists('mb_strlen') ? mb_strlen($group) + 1 : strlen($group) + 1;
2090 $optionValue = substr($zone, $index);
2091
2092 if(strpos($optionValue, 'UTC') !== false){
2093 $optionTitle = str_replace(array('.25', '.5', '.75',), array(':15', ':30', ':45',), $optionValue);
2094 $optionValue = "$optionValue=>$optionTitle";
2095 }else{
2096 $optionValue = "$zone=>$optionValue";
2097 }
2098
2099 $timezones[$group][] = $optionValue;
2100 }
2101
2102 $this->timezones = $timezones;
2103 }
2104
2105 public function get_fields($only_defaults = false){
2106 $this->init_fields();
2107 $fields = $this->fields;
2108
2109 if(!$only_defaults) $fields = apply_filters('wpforo_get_fields', $fields);
2110 return $fields;
2111 }
2112
2113 public function get_register_fields($only_defaults = false){
2114 $this->init_fields();
2115
2116 $regform = array(
2117 $this->fields['user_login'],
2118 $this->fields['user_email']
2119 );
2120 if( !wpforo_feature('user-register-email-confirm') ) $regform[] = $this->fields['user_pass'];
2121 $fields = array(
2122 array(
2123 $regform
2124 )
2125 );
2126
2127 if(!$only_defaults) $fields = apply_filters('wpforo_get_register_fields', $fields);
2128 return $fields;
2129 }
2130
2131 public function get_account_fields($only_defaults = false){
2132 $this->init_fields();
2133
2134 $fields = array(
2135 array(
2136 array(
2137 $this->fields['user_login'],
2138 $this->fields['display_name'],
2139 $this->fields['user_nicename'],
2140 $this->fields['user_email'],
2141 $this->fields['title'],
2142 $this->fields['groupid'],
2143 $this->fields['avatar'],
2144 $this->fields['about'],
2145 $this->fields['site'],
2146 $this->fields['occupation'],
2147 $this->fields['signature']
2148 )
2149 ),
2150 array(
2151 array(
2152 $this->fields['html_soc_net']
2153 ),
2154 array(
2155 $this->fields['facebook'],
2156 $this->fields['gtalk'],
2157 $this->fields['aim'],
2158 $this->fields['msn']
2159 ),
2160 array(
2161 $this->fields['twitter'],
2162 $this->fields['yahoo'],
2163 $this->fields['icq'],
2164 $this->fields['skype']
2165 )
2166 ),
2167 array(
2168 array(
2169 $this->fields['location'],
2170 $this->fields['timezone'],
2171 $this->fields['user_pass']
2172 )
2173 )
2174 );
2175
2176 if(!$only_defaults) $fields = apply_filters('wpforo_get_account_fields', $fields);
2177 return $fields;
2178 }
2179
2180 public function get_profile_fields($only_defaults = false){
2181 $this->init_fields();
2182
2183 $fields = array(
2184 array(
2185 array(
2186 $this->fields['about'],
2187 $this->fields['site'],
2188 )
2189 ),
2190 array(
2191 array(
2192 $this->fields['location'],
2193 $this->fields['timezone'],
2194 $this->fields['occupation'],
2195 $this->fields['signature']
2196 )
2197 ),
2198 array(
2199 array(
2200 $this->fields['html_soc_net']
2201 ),
2202 ),
2203 array(
2204 array(
2205 $this->fields['facebook'],
2206 $this->fields['gtalk'],
2207 $this->fields['aim'],
2208 $this->fields['msn'],
2209 ),
2210 array(
2211 $this->fields['twitter'],
2212 $this->fields['yahoo'],
2213 $this->fields['icq'],
2214 $this->fields['skype']
2215 )
2216 ),
2217 );
2218
2219 if(!$only_defaults) $fields = apply_filters('wpforo_get_profile_fields', $fields);
2220 return $fields;
2221 }
2222
2223 public function get_search_fields($only_defaults = false){
2224 $this->init_fields();
2225
2226 $fields = array(
2227 array(
2228 array(
2229 $this->fields['display_name'],
2230 $this->fields['user_nicename'],
2231 )
2232 )
2233 );
2234
2235 if(!$only_defaults) $fields = apply_filters('wpforo_get_search_fields', $fields);
2236
2237 foreach ($fields as $row_key => $row){
2238 foreach ($row as $col_key => $col){
2239 foreach ($col as $field_key => $field){
2240 $fields[$row_key][$col_key][$field_key]['isRequired'] = 0;
2241 $fields[$row_key][$col_key][$field_key]['class'] = 'wpf-member-search-field';
2242 if( $field['type'] == 'text' || $field['type'] == 'textarea' || $field['type'] == 'email' || $field['type'] == 'url' )
2243 $fields[$row_key][$col_key][$field_key]['type'] = 'search';
2244 }
2245 }
2246 }
2247
2248 return $fields;
2249 }
2250
2251 public function get_search_fields_names($only_defaults = false){
2252 $names = array();
2253 $fields = $this->get_search_fields($only_defaults);
2254
2255 foreach ($fields as $row_key => $row){
2256 foreach ($row as $col_key => $col){
2257 foreach ($col as $field_key => $field){
2258 if( !$field['isDefault'] ) continue;
2259 $names[] = $field['name'];
2260 }
2261 }
2262 }
2263
2264 return $names;
2265 }
2266
2267 public function set_guest_cookies( $args ){
2268 if ( !WPF()->tools_legal['cookies'] ) return false;
2269 if ( isset($args['name']) && isset($args['email']) ) {
2270 $comment_cookie_lifetime = apply_filters( 'comment_cookie_lifetime', 30000000 );
2271 $secure = ( 'https' === parse_url( home_url(), PHP_URL_SCHEME ) );
2272 setcookie( 'comment_author_' . COOKIEHASH, $args['name'], time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure );
2273 setcookie( 'comment_author_email_' . COOKIEHASH, $args['email'], time() + $comment_cookie_lifetime, COOKIEPATH, COOKIE_DOMAIN, $secure );
2274
2275 WPF()->current_user_display_name = $args['name'];
2276 WPF()->current_user_email = $args['email'];
2277 }
2278 }
2279
2280 public function get_guest_cookies(){
2281 if( !WPF()->tools_legal['cookies'] ) return false;
2282 $guest = array(); $guest_cookies = wp_get_current_commenter();
2283 $guest['name'] = ( isset($guest_cookies['comment_author']) ) ? $guest_cookies['comment_author'] : '';
2284 $guest['email'] = ( isset($guest_cookies['comment_author_email']) ) ? $guest_cookies['comment_author_email'] : '';
2285 return $guest;
2286 }
2287
2288 public function edit_is_email_confirmed($userid, $status){
2289 if( false !== WPF()->db->update(
2290 WPF()->tables->profiles,
2291 array( 'is_email_confirmed' => intval($status) ),
2292 array( 'userid' => wpforo_bigintval($userid) ),
2293 array( '%d' ),
2294 array( '%d' )
2295 )
2296 ){
2297 WPF()->notice->add('Email has been confirmed', 'success');
2298 return true;
2299 }
2300 WPF()->notice->add('Email confirm error', 'error');
2301 return false;
2302 }
2303
2304 public function get_is_email_confirmed($userid){
2305 $sql = "SELECT `is_email_confirmed` FROM `".WPF()->tables->profiles."` WHERE `userid` = %d";
2306 return (bool) WPF()->db->get_var( WPF()->db->prepare($sql, $userid) );
2307 }
2308
2309 }