'强制上传头像', 'complete' => '强制完善资料', 'mobile' => '强制手机认证', 'email' => '强制邮箱认证', 'downfile' => '附件下载权限', 'uploadfile' => '附件上传权限', ]; // 用户权限数值项 protected $member_number_fields = [ 'login' => [ 'name' => '每日登录奖励', 'items' => [ 'login_score' => ['app' => 'scorelog', 'unit' => 'score'], 'login_exp' => ['app' => 'explog', 'unit' => 'exp'], ], ], 'avatar_award' => [ 'name' => '头像认证奖励', 'items' => [ 'avatar_score' => ['app' => 'scorelog', 'unit' => 'score'], 'avatar_exp' => ['app' => 'explog', 'unit' => 'exp'], ], ], ]; public function index() { // 用户组列 $group = [ 0 => [ 'id' => 0, 'name' => dr_lang('游客'), 'use' => 1, ] ]; foreach ($this->member_cache['group'] as $t) { $group[$t['id']] = [ 'id' => $t['id'], 'name' => dr_lang($t['name']), 'use' => 1, ]; } // 用户组等级列 $level = [ 0 => [ 'id' => 0, 'name' => dr_lang('游客'), 'group_name' => '', 'level_name' => dr_lang('游客'), 'use' => 1, ] ]; foreach ($this->member_cache['group'] as $t) { $gname = dr_lang($t['name']); $level[$t['id']] = [ 'id' => $t['id'], 'name' => $gname, 'group_name' => '', 'level_name' => $gname, 'use' => 1, ]; if ($t['level']) { foreach ($t['level'] as $lv) { $lname = dr_lang($lv['name']); $level[$t['id'].'-'.$lv['id']] = [ 'id' => $t['id'].'-'.$lv['id'], 'name' => $gname.' / '.$lname, 'group_name' => $gname, 'level_name' => $lname, 'use' => 1, ]; $level[$t['id']]['use'] = 0; } } } $v = \Phpcmf\Service::M()->db->table('member_setting')->where('name', 'auth_type')->get()->getRowArray(); $auth_type = intval($v['value']); // 当前模式对应的列 if ($auth_type == 1) { $columns = $group; } elseif ($auth_type == 2) { $columns = []; foreach ($level as $i => $t) { if ($t['use']) { $columns[$i] = $t; } } } else { $columns = [ 'public' => [ 'id' => 'public', 'name' => dr_lang('全局'), 'use' => 1, ] ]; } // 读取权限 $row = \Phpcmf\Service::M()->db->table('member_setting')->where('name', 'auth2')->get()->getRowArray(); $value = $row ? dr_string2array($row['value']) : []; if (!is_array($value)) { $value = []; } $auth_data = isset($value[SITE_ID]) && is_array($value[SITE_ID]) ? $value[SITE_ID] : []; if (IS_AJAX_POST) { $post = \Phpcmf\Service::L('input')->post('data'); if (!is_array($post)) { $post = []; } foreach ($columns as $aid => $col) { $key = (string)$aid; $old = []; if (isset($auth_data[$aid]) && is_array($auth_data[$aid])) { $old = $auth_data[$aid]; } elseif (isset($auth_data[$key]) && is_array($auth_data[$key])) { $old = $auth_data[$key]; } // 仅读取当前列提交值,且只白名单写入,避免 POST 注入多余字段 $post_member = []; if (isset($post[$aid]['member']) && is_array($post[$aid]['member'])) { $post_member = $post[$aid]['member']; } elseif (isset($post[$key]['member']) && is_array($post[$key]['member'])) { $post_member = $post[$key]['member']; } $member = []; foreach ($this->member_check_fields as $field => $name) { $member[$field] = empty($post_member[$field]) ? 0 : 1; } foreach ($this->member_number_fields as $group_item) { foreach ($group_item['items'] as $field => $cfg) { $member[$field] = isset($post_member[$field]) ? intval($post_member[$field]) : 0; } } $old['member'] = $member; // 应用插件 / 内容权限仍保留,此处不覆盖 $auth_data[$aid] = $old; } $value[SITE_ID] = $auth_data; \Phpcmf\Service::M()->db->table('member_setting')->replace([ 'name' => 'auth2', 'value' => dr_array2string($value) ]); \Phpcmf\Service::M('cache')->sync_cache('member'); $this->_json(1, dr_lang('操作成功')); } $diy = $this->_get_diy(); $col_count = dr_count($columns); $is_single = $col_count <= 1; // 取某列已存 member 配置 $get_member = function ($aid) use ($auth_data) { $key = (string)$aid; if (isset($auth_data[$aid]['member']) && is_array($auth_data[$aid]['member'])) { return $auth_data[$aid]['member']; } if (isset($auth_data[$key]['member']) && is_array($auth_data[$key]['member'])) { return $auth_data[$key]['member']; } return []; }; $form_html = ''; $thead_html = ''; $tbody_html = ''; if ($is_single) { // 全局模式:标准表单排版 $aid = 'public'; foreach ($columns as $k => $col) { $aid = (string)$k; break; } $member = $get_member($aid); $aid_attr = htmlspecialchars($aid); foreach ($this->member_check_fields as $field => $name) { $checked = !empty($member[$field]) ? ' checked' : ''; $form_html .= '
' .'' .'
' .'' .'
'; } foreach ($this->member_number_fields as $item) { $form_html .= '
' .'' .'
'; foreach ($item['items'] as $field => $cfg) { $val = intval(isset($member[$field]) ? $member[$field] : 0); $readonly = (($cfg['app'] == 'scorelog' && !dr_is_app('scorelog')) || ($cfg['app'] == 'explog' && !dr_is_app('explog'))) ? ' readonly' : ''; $unit = $cfg['unit'] == 'score' ? SITE_SCORE : SITE_EXPERIENCE; $form_html .= ''; } $form_html .= '
'; } if (!empty($diy['app'])) { $url = dr_url('member/auth/add', ['aid' => $aid, 'page' => 'app']); $form_html .= '
' .'' .'
' .' '.dr_lang('设置').'' .'
'; } } else { // 多列矩阵 $thead_html = ''.dr_lang('权限项').''; foreach ($columns as $aid => $col) { $key = (string)$aid; if ($key === '0') { $title = ''.htmlspecialchars((string)$col['name']).''; } elseif (!empty($col['group_name'])) { $title = ''.htmlspecialchars((string)$col['group_name']).'' .''.htmlspecialchars((string)$col['level_name']).''; } else { $title = htmlspecialchars((string)$col['name']); } $thead_html .= ''.$title.''; } foreach ($this->member_check_fields as $field => $name) { $tbody_html .= ''.dr_lang($name).''; foreach ($columns as $aid => $col) { $key = (string)$aid; $member = $get_member($aid); $checked = !empty($member[$field]) ? ' checked' : ''; $tbody_html .= '' .'' .''; } $tbody_html .= ''; } foreach ($this->member_number_fields as $item) { $tbody_html .= ''.dr_lang($item['name']).''; foreach ($columns as $aid => $col) { $key = (string)$aid; $member = $get_member($aid); $tbody_html .= ''; foreach ($item['items'] as $field => $cfg) { $val = intval(isset($member[$field]) ? $member[$field] : 0); $readonly = (($cfg['app'] == 'scorelog' && !dr_is_app('scorelog')) || ($cfg['app'] == 'explog' && !dr_is_app('explog'))) ? ' readonly' : ''; $unit = $cfg['unit'] == 'score' ? SITE_SCORE : SITE_EXPERIENCE; $tbody_html .= '
' .'' .'+'.htmlspecialchars((string)$unit).'' .'
'; } $tbody_html .= ''; } $tbody_html .= ''; } if (!empty($diy['app'])) { $tbody_html .= ''.dr_lang('应用插件权限').''; foreach ($columns as $aid => $col) { $key = (string)$aid; $url = dr_url('member/auth/add', ['aid' => $key, 'page' => 'app']); $tbody_html .= '' .' '.dr_lang('设置').'' .''; } $tbody_html .= ''; } } \Phpcmf\Service::V()->assign([ 'menu' => \Phpcmf\Service::M('auth')->_admin_menu( [ '用户权限' => ['member/auth/index', 'fa fa-cog'], 'help' => [801], ] ), 'auth_type' => $auth_type, 'is_single' => $is_single, 'is_cms' => (defined('IS_USE_CMS') && IS_USE_CMS) ? 1 : 0, 'cms_auth_url' => (defined('IS_USE_CMS') && IS_USE_CMS) ? dr_url('cms/auth/index') : '', 'form_html' => $form_html, 'thead_html' => $thead_html, 'tbody_html' => $tbody_html, ]); \Phpcmf\Service::V()->display('member_auth.html'); } // 存储模式值 public function save_edit() { $value = intval(\Phpcmf\Service::L('input')->get('value')); if (!$value) { $msg = dr_lang('已切换至按全局配置模式'); } elseif ($value == 1) { $msg = dr_lang('已切换至按用户组配置模式'); } elseif ($value == 2) { $msg = dr_lang('已切换至按用户组等级配置模式'); } else { $this->_json(0, dr_lang('未知模式')); } \Phpcmf\Service::M()->db->table('member_setting')->replace([ 'name' => 'auth_type', 'value' => $value ]); \Phpcmf\Service::M('cache')->sync_cache('member'); $this->_json(1, $msg); } // 初始化组权限(仅清空用户相关配置,保留内容权限) public function init_edit() { $v = \Phpcmf\Service::M()->db->table('member_setting')->where('name', 'auth2')->get()->getRowArray(); $aid = \Phpcmf\Service::L('input')->get('aid'); if ($aid === null || $aid === false || $aid === '') { $this->_json(0, dr_lang('参数错误')); } // 允许 public / 数字组ID / 组-等级 if ($aid !== 'public' && $aid !== '0' && $aid !== 0 && !preg_match('/^\d+(-\d+)?$/', (string)$aid)) { $this->_json(0, dr_lang('参数错误')); } $value = $v ? dr_string2array($v['value']) : []; if (!is_array($value)) { $value = []; } $old = isset($value[SITE_ID][$aid]) && is_array($value[SITE_ID][$aid]) ? $value[SITE_ID][$aid] : []; // 兼容整型键 if (!$old && is_numeric($aid) && isset($value[SITE_ID][intval($aid)]) && is_array($value[SITE_ID][intval($aid)])) { $old = $value[SITE_ID][intval($aid)]; unset($value[SITE_ID][intval($aid)]); } unset($old['member'], $old['app']); $value[SITE_ID][$aid] = $old; \Phpcmf\Service::M()->db->table('member_setting')->replace([ 'name' => 'auth2', 'value' => dr_array2string($value) ]); \Phpcmf\Service::M('cache')->sync_cache('member'); $this->_json(1, dr_lang('本组权限初始化完成')); } // 兼容:单组详细设置(应用插件扩展权限) public function add() { $aid = \Phpcmf\Service::L('input')->get('aid'); if ($aid == 'public') { $name = dr_lang('全局'); } elseif (!$aid) { $aid = 0; $name = dr_lang('游客'); } elseif (strpos($aid, '-') !== false) { list($gid, $lid) = explode('-', $aid); if (!$this->member_cache['group'][$gid]) { $this->_admin_msg(0, dr_lang('此用户组不存在')); } elseif (!$this->member_cache['group'][$gid]['level'][$lid]) { $this->_admin_msg(0, dr_lang('此用户组等级不存在')); } $name = $this->member_cache['group'][$gid]['name'].'-'.$this->member_cache['group'][$gid]['level'][$lid]['name']; } else { if (!$this->member_cache['group'][$aid]) { $this->_admin_msg(0, dr_lang('此用户组不存在')); } $name = $this->member_cache['group'][$aid]['name']; } $v = \Phpcmf\Service::M()->db->table('member_setting')->where('name', 'auth2')->get()->getRowArray(); $value = $v ? dr_string2array($v['value']) : []; if (!is_array($value)) { $value = []; } $data = isset($value[SITE_ID][$aid]) && is_array($value[SITE_ID][$aid]) ? $value[SITE_ID][$aid] : []; if (IS_AJAX_POST) { $post = \Phpcmf\Service::L('input')->post('data'); if (!is_array($post)) { $post = []; } $save = $data; // 本页仅维护应用插件权限,禁止通过 POST 覆盖用户权限 member if (isset($post['app']) && is_array($post['app'])) { $save['app'] = $post['app']; } $value[SITE_ID][$aid] = $save; \Phpcmf\Service::M()->db->table('member_setting')->replace([ 'name' => 'auth2', 'value' => dr_array2string($value) ]); \Phpcmf\Service::M('cache')->sync_cache('member'); $this->_json(1, dr_lang('操作成功')); } $page = trim(\Phpcmf\Service::L('input')->get('page')); if (!$page) { $page = 'app'; } \Phpcmf\Service::V()->assign([ 'aid' => $aid, 'diy' => $this->_get_diy(), 'menu' => \Phpcmf\Service::M('auth')->_admin_menu( [ '返回' => ['member/auth/index', 'fa fa-cog'], dr_lang('%s:应用权限', $name) => ['member/auth/add{aid='.$aid.'}', 'fa fa-puzzle-piece'], 'help' => [801], ] ), 'page' => $page, 'data' => $data, 'is_ajax_edit' => 0, ]); \Phpcmf\Service::V()->display('member_auth_setting.html'); } public function edit() { $this->_json(0, dr_lang('内容权限请到【内容系统 → 权限设置 → 内容权限】中配置')); } public function copy_edit() { $at = dr_safe_filename(\Phpcmf\Service::L('input')->get('at')); if (!$at) { $this->_json(0, dr_lang('at参数错误')); } $v = \Phpcmf\Service::M()->db->table('member_setting')->where('name', 'auth2')->get()->getRowArray(); $aid = dr_safe_filename(\Phpcmf\Service::L('input')->get('aid')); !$aid && $aid = 0; $value = dr_string2array($v['value']); switch ($at) { case 'level': $group = [ 0 => [ 'id' => 0, 'name' => dr_lang('游客'), ], ]; foreach ($this->member_cache['group'] as $t) { $group[$t['id']] = [ 'id' => $t['id'], 'name' => dr_lang($t['name']), ]; if ($t['level']) { foreach ($t['level'] as $lv) { $group[$t['id'].'-'.$lv['id']] = [ 'id' => $t['id'].'-'.$lv['id'], 'name' => ' └ '.dr_lang($lv['name']), ]; } } } if (IS_AJAX_POST) { $auth = $value[SITE_ID][$aid]; if (!$auth) { $this->_json(0, dr_lang('当前用户组没有配置权限规则')); } $catids = \Phpcmf\Service::L('input')->post('catid'); if (!$catids) { $this->_json(0, dr_lang('你还没有选择用户组呢')); } $c = 0; if (isset($catids[0]) && $catids[0] == 0) { foreach ($group as $id => $t) { $c ++; $value[SITE_ID][$id] = $auth; } } else { foreach ($catids as $id) { $c ++; $value[SITE_ID][$id] = $auth; } } \Phpcmf\Service::M()->db->table('member_setting')->replace([ 'name' => 'auth2', 'value' => dr_array2string($value) ]); \Phpcmf\Service::M('cache')->sync_cache('member'); $this->_json(1, dr_lang('共复制%s个用户组', $c)); exit; } \Phpcmf\Service::V()->assign([ 'form' => dr_form_hidden(), 'select' => \Phpcmf\Service::L('tree')->select_category( $group, 0, 'id=\'dr_catid\' name=\'catid[]\' multiple="multiple" style="height:200px"', '', 0, 0 ), ]); \Phpcmf\Service::V()->display('member_auth_copy_group.html');exit; case 'group': $group = [ 0 => [ 'id' => 0, 'name' => dr_lang('游客'), ], ]; foreach ($this->member_cache['group'] as $t) { $group[$t['id']] = $t; } if (IS_AJAX_POST) { $auth = $value[SITE_ID][$aid]; if (!$auth) { $this->_json(0, dr_lang('当前用户组没有配置权限规则')); } $catids = \Phpcmf\Service::L('input')->post('catid'); if (!$catids) { $this->_json(0, dr_lang('你还没有选择用户组呢')); } $c = 0; if (isset($catids[0]) && $catids[0] == 0) { foreach ($group as $id => $t) { $c ++; $value[SITE_ID][$id] = $auth; } } else { foreach ($catids as $id) { $c ++; $value[SITE_ID][$id] = $auth; } } \Phpcmf\Service::M()->db->table('member_setting')->replace([ 'name' => 'auth2', 'value' => dr_array2string($value) ]); \Phpcmf\Service::M('cache')->sync_cache('member'); $this->_json(1, dr_lang('共复制%s个用户组', $c)); exit; } \Phpcmf\Service::V()->assign([ 'form' => dr_form_hidden(), 'select' => \Phpcmf\Service::L('tree')->select_category( $group, 0, 'id=\'dr_catid\' name=\'catid[]\' multiple="multiple" style="height:200px"', '', 0, 0 ), ]); \Phpcmf\Service::V()->display('member_auth_copy_group.html');exit; case 'share_category': case 'category': $this->_json(0, dr_lang('内容权限请到【内容系统 → 权限设置 → 内容权限】中配置')); break; } $this->_json(0, dr_lang('未知类型')); } private function _get_diy() { $diy = [ 'member' => [], 'app' => [], ]; $local = \Phpcmf\Service::Apps(1); foreach ($local as $dir => $path) { if (is_file($path.'Config/Auth.php')) { $_data = require $path.'Config/Auth.php'; if ($_data) { foreach ($_data as $key => $val) { if ($val && isset($diy[$key])) { foreach ($val as $file) { if (is_file($path.'Views/auth/'.$file)) { $diy[$key][] = [ 'app' => $dir, 'file' => $path.'Views/auth/'.$file, ]; } else { log_message('error', '应用插件['.$dir.']权限模板文件不存在:'.$path.'Views/auth/'.$file); } } } } } } } return $diy; } }