<?php
// 权限模型

namespace app\model;

class AuthGroup extends BaseModel
{
    const TYPE_ADMIN                = 1;                   // 管理员用户组类型标识
    const MEMBER                    = 'agents';
    const AUTH_GROUP_ACCESS         = 'auth_group_access'; // 关系表表名
    const AUTH_GROUP                = 'auth_group';        // 用户组表名
    const AUTH_EXTEND_CATEGORY_TYPE = 1;              // 分类权限标识
    const AUTH_EXTEND_MODEL_TYPE    = 2; //分类权限标识

    protected $insert =['status'=>1];

    /**
     * 返回用户组列表
     * 默认返回正常状态的管理员用户组列表
     * @param array $where   查询条件,供where()方法使用
     *
     */
    public function getGroups($where=array()){
        $map = array('status'=>1);
        $map = array_merge($map,$where);
        return $this->where($map)->select();
    }

    /**
     * 把用户添加到用户组,支持批量添加用户到用户组
     * 
     * 示例: 把uid=1的用户添加到group_id为1,2的组 `AuthGroupModel->addToGroup(1,'1,2');`
     */
    public function addToGroup($uid, $gid){
        $uid = is_array($uid)? implode(',',$uid) : trim($uid,',');
        $gid = is_array($gid)? $gid:explode( ',',trim($gid,',') );

        $Access = model(self::AUTH_GROUP_ACCESS);
        $del = true;
        if( isset($_REQUEST['batch']) ){
            //为单个用户批量添加用户组时,先删除旧数据
            $del = $Access->where(['uid'=>['in',$uid]])->delete();
        }

        $uid_arr = explode(',',$uid);
        $uid_arr = array_diff($uid_arr,get_administrators());
        $add = [];
        if( $del!==false ){
            foreach ($uid_arr as $u){
                foreach ($gid as $g){
                    if( is_numeric($u) && is_numeric($g) ){
                        //防止重复添加
                        if (!$Access->where(['group_id'=>$g,'uid'=>$u])->count()) {
                            $add[] = ['group_id'=>$g,'uid'=>$u];
                        }
                        
                    }
                }
            }

            if (!empty($add) && is_array($add)) {
                $Access->saveAll($add);
            } else{
                $this->error = "添加失败，可能有重复添加操作";
                return false;
            }
            
        }
        if ($Access->getError()) {
            if( count($uid_arr)==1 && count($gid)==1 ){
                //单个添加时定制错误提示
                $this->error = "不能重复添加";
            }
            return false;
        } 
        return true;

    }

    /**
     * 返回用户所属用户组信息
     * @param  int    $uid 用户id
     * @return array  用户所属的用户组 array(
     *                                         array('uid'=>'用户id','group_id'=>'用户组id','title'=>'用户组名称','rules'=>'用户组拥有的规则id,多个,号隔开'),
     *                                         ...)   
     */
    static public function getUserGroup($uid){
        static $groups = array();
        if (isset($groups[$uid]))
            return $groups[$uid];
        $prefix   = config('database.prefix');
        $user_groups = model()
            ->field('uid,group_id,title,description,rules')
            ->table($prefix.self::AUTH_GROUP_ACCESS.' a')
            ->join ($prefix.self::AUTH_GROUP." g on a.group_id=g.id")
            ->where("a.uid='$uid' and g.status='1'")
            ->select();
        $groups[$uid]=$user_groups?$user_groups:array();
        return $groups[$uid];
    }
    
    /**
     * 将用户从用户组中移除
     * @param int|string|array $gid   用户组id
     * @param int|string|array $cid   分类id
     */
    public function removeFromGroup($uid,$gid){
        $del_result = model(self::AUTH_GROUP_ACCESS)->where( array( 'uid'=>$uid,'group_id'=>$gid) )->delete();
        if ($del_result) {
            $user_auth_role = db('users')->where(array('uid'=>$uid))->value('auth_groups');
            if ($user_auth_role) {
                $user_auth_role=array_merge(array_diff(explode(',', $user_auth_role), array($gid)));
                model('user')->where(array('uid'=>$uid))->setField('auth_groups',$user_auth_role);//同时将用户角色关联删除
            }
            
        }
        return $del_result;
    }

    /**
     * 获取某个用户组的用户列表
     *
     * @param int $group_id   用户组id
     */
    static public function userInGroup($group_id){
        $prefix   = config('database.prefix');
        $l_table  = $prefix.self::MEMBER;
        $r_table  = $prefix.self::AUTH_GROUP_ACCESS;
        $list     = model() ->field('m.uid,u.username,m.last_login_time,m.last_login_ip,m.status')
                       ->table($l_table.' m')
                       ->join($r_table.' a ON m.uid=a.uid')
                       ->where(array('a.group_id'=>$group_id))
                       ->select();
        return $list;
    }

    /**
     * 检查id是否全部存在
     * @param array|string $gid  用户组id列表
     */
    public function checkId($modelname,$mid,$msg = '以下id不存在:'){
        if(is_array($mid)){
            $count = count($mid);
            $ids   = implode(',',$mid);
        }else{
            $mid   = explode(',',$mid);
            $count = count($mid);
            $ids   = $mid;
        }

        $s = model($modelname)->where(array('id'=>array('in',$ids)))->column('id');
        if(count($s)===$count){
            return true;
        }else{
            $diff = implode(',',array_diff($mid,$s));
            $this->error = $msg.$diff;
            return false;
        }
    }

    /**
     * 检查用户组是否全部存在
     * @param array|string $gid  用户组id列表
     */
    public function checkGroupId($gid){
        return $this->checkId('AuthGroup',$gid, '以下用户组id不存在:');
    }


    
    /**
     * 返回角色分组
     * 
     * @param type $pageNo
     * @param type $pageSize
     * @param type $order_
     * @param type $field
     * @param type $params
     * @return type
     */
    public function getList($pageNo = 1, $pageSize = 15, $order_ = 'id desc', $field = '', $params = '') {
        return $this->field($field)
                ->where($params)
                ->order($order_)
                ->limit($pageSize)
                ->page($pageNo)
                ->select();
    }
    /**
     *检查重复
     *
     */
    public function repetition($key,$name){
        $r=$this->field($name)
            ->where($key,$name)
            ->select();
        if($r){
           return true;
        }else{
            return false;
        }
}

}
