init_defaults(); $this->cans = apply_filters( 'wpforo_usergroup_cans', $this->default->cans ); $this->init_hooks(); } private function init_defaults() { $this->default = new stdClass; $this->default->default_groupid = 3; $this->default->group = [ 'groupid' => 0, 'name' => '', 'cans' => '', 'description' => '', 'utitle' => '', 'role' => '', 'access' => '', 'color' => '', 'visible' => 0, 'secondary' => 0, 'is_default' => 0, ]; $this->default->post_flood_intervals = [ 0 => 0, 1 => 0, 2 => 0, 3 => 0, 4 => 0, 5 => 0, ]; $this->default->cans = [ 'mf' => __( 'Dashboard - Manage Boards & Forums', 'wpforo' ), 'ms' => __( 'Dashboard - Manage Settings', 'wpforo' ), 'mai' => __( 'Dashboard - Manage AI Features', 'wpforo' ), 'mt' => __( 'Dashboard - Manage Tools', 'wpforo' ), 'vm' => __( 'Dashboard - Manage Members', 'wpforo' ), 'aum' => __( 'Dashboard - Moderate Topics & Posts', 'wpforo' ), 'vmg' => __( 'Dashboard - Manage Usergroups', 'wpforo' ), 'mp' => __( 'Dashboard - Manage Phrases', 'wpforo' ), 'mth' => __( 'Dashboard - Manage Themes', 'wpforo' ), 'em' => __( 'Dashboard - Can edit member', 'wpforo' ), 'bm' => __( 'Dashboard - Can ban member', 'wpforo' ), 'dm' => __( 'Dashboard - Can delete member', 'wpforo' ), 'aup' => __( 'Front - Can pass moderation', 'wpforo' ), 'view_stat' => __( 'Front - Can view statistic', 'wpforo' ), 'vmem' => __( 'Front - Can view members', 'wpforo' ), 'vprf' => __( 'Front - Can view profiles', 'wpforo' ), 'vpra' => __( 'Front - Can view member activity', 'wpforo' ), 'vprs' => __( 'Front - Can view member subscriptions', 'wpforo' ), 'upc' => __( 'Front - Can upload cover', 'wpforo' ), 'upa' => __( 'Front - Can upload avatar', 'wpforo' ), 'ups' => __( 'Front - Can have signature', 'wpforo' ), 'va' => __( 'Front - Can view avatars', 'wpforo' ), 'vmu' => __( 'Front - Can view member username', 'wpforo' ), 'vmm' => __( 'Front - Can view member email', 'wpforo' ), 'vmt' => __( 'Front - Can view member title', 'wpforo' ), // 'vmct' => __( 'Front - Can view member custom title', 'wpforo' ), 'vmr' => __( 'Front - Can view member reputation', 'wpforo' ), 'vmw' => __( 'Front - Can view member website', 'wpforo' ), 'vmsn' => __( 'Front - Can view member social networks', 'wpforo' ), 'vmrd' => __( 'Front - Can view member reg. date', 'wpforo' ), 'vml' => __( 'Front - Can view member location', 'wpforo' ), 'vmo' => __( 'Front - Can view member occupation', 'wpforo' ), 'vms' => __( 'Front - Can view member signature', 'wpforo' ), 'vmam' => __( 'Front - Can view member about me', 'wpforo' ), 'vwpm' => __( 'Front - Can write PM', 'wpforo' ), 'caa' => __( 'Front - Can access to attachments', 'wpforo' ), 'vt_add_topic' => __( 'Front - Can access to add topic page', 'wpforo' ), 'ai_search' => __( 'Front - Can use AI semantic search', 'wpforo' ), 'ai_summary' => __( 'Front - Can use AI topic summarization', 'wpforo' ), 'ai_translation' => __( 'Front - Can use AI post translation', 'wpforo' ), 'ai_suggestion' => __( 'Front - Can see AI topic suggestion', 'wpforo' ), ]; } private function init_options() { $this->default_groupid = $this->get_default_groupid( $this->default->default_groupid ); $this->post_flood_intervals = wpforo_get_option( 'wpforo_post_flood_intervals', $this->default->post_flood_intervals ); } public function init_current() { if( ! $this->current = $this->get_usergroup( WPF()->current_user_groupid ) ) { $this->current = $this->get_usergroup(); } } private function init_hooks() { // add_action('wpforo_after_add_usergroup', array($this, 'after_add_edit_usergroup')); // add_action('wpforo_after_edit_usergroup', array($this, 'after_add_edit_usergroup')); if( WPF()->is_installed() ) $this->init_options(); } public function get_flood_interval( $groupid, $obj = 'post' ) { $flood_interval = ( wpfkey( $this->post_flood_intervals, $groupid ) ? $this->post_flood_intervals[ $groupid ] : 3 ); return apply_filters( 'wpforo_usergroup_get_flood_interval', intval( $flood_interval ), $groupid, $obj ); } public function fix_group( $group ) { $group = wpforo_array_args_cast_and_merge( (array) $group, $this->default->group ); $cans = array_map( '__return_zero', $this->cans ); $group['cans'] = maybe_unserialize( $group['cans'] ); if( is_array( $group['cans'] ) ) { $group['cans'] = wpforo_array_args_cast_and_merge( $group['cans'], $cans ); } else { $group['cans'] = $cans; } return $group; } function usergroup_list_data() { $ugdata = []; $groups = WPF()->db->get_results( 'SELECT * FROM ' . WPF()->tables->usergroups . ' ORDER BY `name` ', ARRAY_A ); foreach( $groups as $group ) { $user_count = WPF()->db->get_var( "SELECT COUNT(*) FROM " . WPF()->tables->profiles . " WHERE `groupid` = " . intval( $group['groupid'] ) . " OR FIND_IN_SET(" . intval( $group['groupid'] ) . ", `secondary_groupids`)" ); $ugdata[ $group['groupid'] ]['groupid'] = intval( $group['groupid'] ); $ugdata[ $group['groupid'] ]['name'] = wpforo_phrase( $group['name'], false ); $ugdata[ $group['groupid'] ]['role'] = $group['role']; $ugdata[ $group['groupid'] ]['count'] = intval( $user_count ); $ugdata[ $group['groupid'] ]['access'] = $group['access']; $ugdata[ $group['groupid'] ]['color'] = $group['color']; $ugdata[ $group['groupid'] ]['secondary'] = $group['secondary']; } return $ugdata; } function add( $title, $cans = [], $description = '', $role = 'subscriber', $access = 'standard', $color = '', $visible = 1, $secondary = 0 ) { $i = 2; $real_title = $title; while( WPF()->db->get_var( WPF()->db->prepare( "SELECT `groupid` FROM `" . WPF()->tables->usergroups . "` WHERE `name` = %s", sanitize_text_field( $title ) ) ) ) { $title = $real_title . '-' . $i; $i ++; } $group = [ 'name' => sanitize_text_field( $title ), 'cans' => serialize( wpforo_parse_args( $cans, array_map( '__return_zero', $this->cans ) ) ), 'description' => $description, 'utitle' => sanitize_text_field( $real_title ), 'role' => $role, 'access' => $access, 'color' => $color, 'visible' => $visible, 'secondary' => $secondary, ]; if( WPF()->db->insert( WPF()->tables->usergroups, $group, [ '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d' ] ) ) { $group['groupid'] = WPF()->db->insert_id; do_action( 'wpforo_after_add_usergroup', $group ); WPF()->notice->add( 'User group successfully added', 'success' ); return $group['groupid']; } WPF()->notice->add( 'User group add error', 'error' ); return false; } function edit( $groupid, $title, $cans, $description = '', $role = null, $access = null, $color = '', $visible = 1, $secondary = 0 ) { if( ! $this->can( 'vmg' ) ) { WPF()->notice->add( 'Permission denied', 'error' ); return false; } if( $groupid = intval( $groupid ) ) { $old_group = $this->get_usergroup( $groupid ); $group = [ 'name' => sanitize_text_field( $title ), 'cans' => serialize( wpforo_parse_args( $cans, array_map( '__return_zero', $this->cans ) ) ), 'description' => $description, 'utitle' => $old_group['utitle'], 'role' => is_null( $role ) ? $old_group['role'] : $role, 'access' => is_null( $access ) ? $old_group['access'] : $access, 'color' => $color, 'visible' => $visible, 'secondary' => $secondary, ]; if( false !== WPF()->db->update( WPF()->tables->usergroups, $group, [ 'groupid' => $groupid ], [ '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%d', '%d' ], [ '%d' ] ) ) { $group['groupid'] = $groupid; do_action( 'wpforo_after_edit_usergroup', $group ); WPF()->notice->add( 'User group successfully edited', 'success' ); return $groupid; } } WPF()->notice->add( 'User group edit error', 'error' ); return false; } function delete( $groupid, $mergeid ) { if( ! $this->can( 'vmg' ) ) { WPF()->notice->add( 'Permission denied', 'error' ); return false; } if( ( $groupid = intval( $groupid ) ) && ! in_array( $groupid, [ 1, 4 ] ) ) { if( $mergeid = intval( $mergeid ) ) { $sql = "UPDATE `" . WPF()->tables->profiles . "` SET `groupid` = %d WHERE `groupid` = %d"; WPF()->db->query( WPF()->db->prepare( $sql, $mergeid, $groupid ) ); } if( false !== WPF()->db->delete( WPF()->tables->usergroups, [ 'groupid' => $groupid ], [ '%d' ] ) ) { WPF()->notice->add( wpforo_phrase( 'Usergroup has been successfully deleted. All users of this usergroup have been moved to the usergroup you\'ve chosen', false ), 'success' ); return $groupid; } } WPF()->notice->add( 'Can\'t delete this Usergroup', 'error' ); return false; } public function _get_usergroup( $groupid = 4 ) { return WPF()->db->get_row( WPF()->db->prepare( "SELECT * FROM `" . WPF()->tables->usergroups . "` WHERE `groupid` = %d", $groupid ), ARRAY_A ); } public function get_usergroup( $groupid = 4 ) { return wpforo_ram_get( [ $this, '_get_usergroup' ], $groupid ); } public function _get_usergroups( $field = 'full' ) { if( $field === 'full' ) { $groups = (array) WPF()->db->get_results( "SELECT * FROM `" . WPF()->tables->usergroups . "`", ARRAY_A ); } else { $groups = WPF()->db->get_col( "SELECT `$field` FROM `" . WPF()->tables->usergroups . "`" ); } return $groups; } public function get_usergroups( $field = 'full' ) { return wpforo_ram_get( [ $this, '_get_usergroups' ], $field ); } /** * @param array|int $selected * @param array|int $exclude * * @return string */ public function get_selectbox( $selected = [], $exclude = [] ) { $selected = array_map( 'intval', (array) $selected ); $exclude = array_map( 'intval', (array) $exclude ); $html = ''; foreach( $this->usergroup_list_data() as $group ) { if( in_array( $group['groupid'], $exclude ) ) continue; $html .= sprintf( '', intval( $group['groupid'] ), in_array( $group['groupid'], $selected ) ? ' selected ' : '', esc_html( $group['name'] ) . "\t(" . $group['count'] . ")" ); } return $html; } /** * @param array|int $selected * @param array|int $exclude */ public function show_selectbox( $selected = [], $exclude = [] ) { echo $this->get_selectbox( $selected, $exclude ); } function get_visible_usergroup_ids() { $key = [ 'usergroup', 'get_visible_usergroup_ids' ]; if( WPF()->ram_cache->exists( $key ) ) return WPF()->ram_cache->get( $key ); $col = WPF()->db->get_col( "SELECT `groupid` FROM `" . WPF()->tables->usergroups . "` WHERE `visible` = 1" ); WPF()->ram_cache->set( $key, $col ); return $col; } public function _get_secondary_groupids() { return WPF()->db->get_col( "SELECT `groupid` FROM `" . WPF()->tables->usergroups . "` WHERE `groupid` NOT IN(1,2,4) AND `secondary` = 1" ); } public function get_secondary_groupids() { return wpforo_ram_get( [$this, '_get_secondary_groupids'] ); } function get_secondary_group_names( $ids ) { if( ! is_array( $ids ) ) $ids = explode( ',', $ids ); $ids = array_map( 'intval', $ids ); $ids = array_diff( $ids, [ 1, 2, 4 ] ); if( $ids ) { $ids = implode( ',', $ids ); return WPF()->db->get_col( "SELECT `name` FROM `" . WPF()->tables->usergroups . "` WHERE `secondary` = 1 AND `groupid` IN (" . esc_sql( $ids ) . ")" ); } return []; } /** * @deprecated since 2.1.6, instead of this method you can use $this->get_secondary_groups() */ function get_secondary_usergroups() { return $this->get_secondary_groups(); } function get_secondary_groups() { return wpforo_ram_get( [ $this, '_get_secondary_groups' ] ); } function _get_secondary_groups() { $order_by = apply_filters('wpforo_get_secondary_groups_order_by', 'ORDER BY `groupid` ASC'); return (array) WPF()->db->get_results( "SELECT * FROM `" . WPF()->tables->usergroups . "` WHERE `groupid` NOT IN(1,2,4) AND `secondary` = 1 " . esc_sql( $order_by ), ARRAY_A ); } function get_groupids_by_role( $role ) { if( $role ) { $ugids = WPF()->db->get_col( "SELECT `groupid` FROM `" . WPF()->tables->usergroups . "` WHERE `role` = '" . esc_sql( $role ) . "' ORDER BY `groupid` ASC" ); if( ! empty( $ugids ) ) { return $ugids; } } return null; } function get_group_by_role( $role ) { if( $role ) { $usergroups = WPF()->db->get_results( "SELECT * FROM `" . WPF()->tables->usergroups . "` WHERE `role` = '" . esc_sql( $role ) . "' ORDER BY `groupid` ASC", ARRAY_A ); if( ! empty( $usergroups ) ) { return $usergroups; } } return null; } function get_roles() { $roles = wp_roles(); $roles = $roles->get_names(); return $roles; } function get_roles_ug() { $roles_ug = WPF()->db->get_results( "SELECT `name`, `role` FROM `" . WPF()->tables->usergroups . "`", ARRAY_A ); $roles = wp_roles(); $roles = $roles->get_names(); if( ! empty( $roles ) ) { foreach( $roles as $role => $name ) { foreach( $roles_ug as $ug ) { if( wpfval( $ug, 'role' ) && $role == $ug['role'] ) { $roles_ug[ $role ][] = $ug['name']; } } } } return $roles_ug; } function get_roles_woug() { $roles_woug = []; $roles_ug = WPF()->db->get_col( "SELECT `role` FROM `" . WPF()->tables->usergroups . "` GROUP BY `role`" ); $roles = wp_roles(); $roles = $roles->get_names(); if( ! empty( $roles ) ) { foreach( $roles as $role => $name ) { if( ! in_array( $role, $roles_ug ) ) { $roles_woug[ $role ] = $name; } } } return $roles_woug; } function get_role_usergroup_relation() { $roles = []; $data = WPF()->db->get_results( "SELECT `groupid`, `role` FROM `" . WPF()->tables->usergroups . "` ORDER BY `groupid` DESC", ARRAY_A ); if( ! empty( $data ) ) { $data = array_map( function($d){ $d['groupid'] = intval( $d['groupid'] ); return $d; }, $data ); foreach( $data as $rel ) { if( $rel['groupid'] === 1 && in_array( $rel['role'], [ 'subscriber', 'contributor' ], true ) ) { $roles['administrator'] = $rel['groupid']; } elseif( $rel['groupid'] === 2 && $rel['role'] === 'subscriber' ) { $roles['editor'] = $rel['groupid']; } elseif( $rel['role'] ) { $roles[ $rel['role'] ] = $rel['groupid']; } } } return $roles; } function get_usergroup_role_relation() { $usergroups = []; $data = WPF()->db->get_results( "SELECT `groupid`, `role` FROM `" . WPF()->tables->usergroups . "`", ARRAY_A ); if( ! empty( $data ) ) { foreach( $data as $rel ) { $usergroups[ $rel['groupid'] ] = $rel['role']; } } return $usergroups; } function get_usergroup_access_relation() { $usergroups = []; $data = WPF()->db->get_results( "SELECT `groupid`, `access` FROM `" . WPF()->tables->usergroups . "`", ARRAY_A ); if( ! empty( $data ) ) { foreach( $data as $rel ) { $usergroups[ (int) $rel['groupid'] ] = $rel['access']; } } return $usergroups; } function set_ug_roles( $ug_role ) { if( ! empty( $ug_role ) ) { foreach( $ug_role as $usergroupid => $role ) { $role = sanitize_text_field( $role ); WPF()->db->query( "UPDATE " . WPF()->tables->usergroups . " SET `role` = '" . esc_sql( $role ) . "' WHERE `groupid` = " . intval( $usergroupid ) ); } } } function set_users_groupid( $groupid_userids ) { $status = [ 'error' => 0, 'success' => false ]; if( ! empty( $groupid_userids ) ) { foreach( $groupid_userids as $group_id => $user_ids ) { if( $group_id && ! empty( $user_ids ) ) { $userids = implode( ',', $user_ids ); $sql = "UPDATE " . WPF()->tables->profiles . " SET `groupid` = " . intval( $group_id ) . " WHERE `userid` IN(" . esc_sql( $userids ) . ")"; if( false === WPF()->db->query( $sql ) ) { $status['error'] = WPF()->db->last_error; $status['success'] = false; break; } else { $status['success'] = true; } } } } do_action( 'wpforo_set_users_groupid', $groupid_userids, $status ); return $status; } function build_users_groupid_array( $groupid_role_or_role_groupid, $users, $is_groupid_role = false ) { $array = []; $group_users = []; $user_prime_group = []; $user_second_groups = []; if( ! empty( $users ) ) { foreach( $users as $user ) { if( ! empty( $user->roles ) ) { foreach( $user->roles as $role ) { //$ugids = wpforo_key( $usergroupid_role, $role, 'sort' ); $ugids = []; if( !empty( $groupid_role_or_role_groupid ) ){ if( ! $is_groupid_role ){ foreach ( $groupid_role_or_role_groupid as $_role => $_groupid ){ if( $_role === $role ){ $ugids[] = $_groupid; } } } else { foreach ( $groupid_role_or_role_groupid as $_groupid => $_role ){ if( $_role === $role ){ $ugids[] = $_groupid; } } } } sort( $ugids ); $ug_count = count( $ugids ); if( ! empty( $ugids ) ) { foreach( $ugids as $ugid ) { // The count of $ug_count === 1 means the user role is synced, // it has one unique usergroup. if( $ug_count === 1 ) { if( ! isset( $user_prime_group[ $user->ID ] ) ) { $user_prime_group[ $user->ID ][] = $ugid; $group_users[ $ugid ][] = intval( $user->ID ); } else { $user_second_groups[ $user->ID ][] = $ugid; } } } } } } } } $array['group_users'] = $group_users; $array['user_prime_group'] = $user_prime_group; $array['user_second_groups'] = $user_second_groups; return $array; } public function after_add_edit_usergroup( $group ) { if( wpforo_setting( 'authorization', 'role_synch' ) ) { $limit = apply_filters( 'wpforo_synch_roles_users_limit', 5000 ); $users = get_users( [ 'role' => $group['role'], 'number' => $limit ] ); if( ! empty( $users ) ) { if( count( $users ) <= $limit ) { $status = wpforo_synch_role( [ $group['groupid'] => $group['role'] ], $users ); wpforo_clean_cache( 'user' ); if( $error = wpfval( $status, 'error' ) ) { WPF()->notice->add( $error, 'error' ); } } else { WPF()->notice->add( 'Please make sure you don\'t have not-synched Roles in the "User Roles" table below, then click on the [Synchronize] button to update users Usergroup IDs.', 'error' ); } } } } public function can( $do, $groupids = null ) { if( is_null( $groupids ) ) { if( current_user_can( 'administrator' ) ) return 1; $groupids = WPF()->current_user_groupids; } if( $groupids = array_map( 'intval', (array) $groupids ) ) { foreach( $groupids as $groupid ) { if( $groupid ) { $group = $this->get_usergroup( $groupid ); if( wpfval( $group, 'cans' ) ){ $group_cans = unserialize( $group['cans'] ); if( (int) wpfval( $group_cans, $do ) ) return 1; } } } } return 0; } public function get_groupids_by_can( $do ) { $usergroupids = []; $usergroups = $this->get_usergroups(); foreach( $usergroups as $usergroup ) { $cans = unserialize( $usergroup['cans'] ); if( isset( $cans[ $do ] ) && $cans[ $do ] ) { $usergroupids[] = $usergroup['groupid']; } } return $usergroupids; } public function can_manage_forum( $groupids = null ) { return ( $this->can( 'cf', $groupids ) && $this->can( 'ef', $groupids ) && $this->can( 'df', $groupids ) ) || $this->can( 'mf', $groupids ); } public function set_default( $groupid ) { if( in_array( intval($groupid), [1,4], true ) ) return false; if( WPF()->db->update( WPF()->tables->usergroups, ['is_default' => 1], ['groupid' => $groupid], ['%d'], ['%d'] )){ return false !== WPF()->db->query( WPF()->db->prepare( "UPDATE `" . WPF()->tables->usergroups . "` SET `is_default` = 0 WHERE `groupid` <> %d", $groupid )); } return false; } public function get_default_groupid( $default_groupid ){ $groupid = (int) WPF()->db->get_var( "SELECT `groupid` FROM `" . WPF()->tables->usergroups . "` WHERE `is_default` = 1 ORDER BY `groupid` DESC" ); if( !$groupid ) $groupid = $default_groupid; return $groupid; } }