<?php
/**
 * 权限取值与判断
 * @
 */
class p {
    public static $data = null;
    public static $xorFags = [
        'view'=>1,'add'=>2,'edit'=>4,'delete'=>8,
        'import'=>16,'export'=>32,'done'=>64,
        'check1'=>128,'check2'=>256,'check3'=>512
    ];

    /**
     * 是否存在指定的权限
     * @param ...  可变参数  
     * 
     * has('code1','view');
     * 
     * has('code1',['view','done']);
     * 
     * has('code1','*');
     * 
     * has([
     *      'code1' => ['view','done'],
     *      'code2' => ['view'],
     * ]);
     * 
     * has([
     *      'OR'=>[
     *          'code1' => ['view','done'],
     *          'code2' => 'view',
     *      ]
     * ]);
     * 
     * @return bool
     */
    public static function has(...$args){
        if(self::isAdmin()){
            return true;
        }
        self::init();
        $argsCount = count($args);
        if($argsCount == 2){
            $code  = $args[0];
            $power = $args[1];
            if(!is_array($power)) $power= [$power];
            $params = [$code=>$power];
        }else{
            $params = $args[0];
        }
        $isOr = ($params['OR']!=null);
        if($isOr) $params = $params['OR'];
        foreach($params as $code=>$power){
            self::checkCode($code);
            $v = self::checkXor(self::$data[$code]['prl_value'],$power);
            if($isOr && $v)
                return true;
            else if(!$v)
                return false;
        }
        return !$isOr;
    }
    
    
    /**
     * 权限判断
     * @param int $value  拥有的权限值  
     * @param array $power  权限标识 ['view','edit']  
     * @return bool
     */
    public static function checkXor($value,$power){
        if($power=='*') return true;
 		$result = true;
 		foreach($power as $fag){
 		    $v = (int)self::$xorFags[$fag];
 		    if(empty($v)){
    			throw new \Exception( sprintf("[%s] %s", $fag, lg("未知的权限标识")) );
 		    }
 		    if( false == (($v ^ (int)$value ) < (int)$value) )
 		        return false;
 		}
 		return true;
    }
    
    /**
     * 错误输出
     * @return void
     */
     public static function error($msg='非法操作 (Illegal operation)[P]'){
 		ob_clean();
		header('HTTP/1.0 401 Unauthorized');
		exit('
		<script>
		var localFag ="qg_'.\mvc::$cfg['project'].'_'.\mvc::$cfg['site'].'";
		var data = localStorage[localFag];
		if (data != null){
			data=JSON.parse(data);
			delete data["pageRefresh"];
			var newdata = {};
			$.each(data,function(i,e){
				if(typeof(e)!="undefined" && e!=null)	newdata[i] = e;
			});
			data = JSON.stringify(newdata);
			localStorage[localFag] = data;
		}
		//parent.window.location.href="'.\mvc::$cfg['sitePath'].'/user/logout";
		</script>
		<h1>ERROR 401</h1><p>'.$msg.'</p>'
		);
    }
    
    /**
     * 初始化
     * @return void
     */
    public static function init($uid = null, $table = null){
        if(self::$data == null){
            self::$data = self::getData($uid, $table);
            //if(empty(self::$data)) self::error();
        }
     }
    
    /**
     * 初始化
     * @return void
     */
    public static function getData($uid = null, $table = null){
        if(!empty($_SESSION['powerData'])){
            self::$data = $_SESSION['powerData'];
        }
        if(self::$data == null){
            //使用 SESSION 记录，可提高性能
			if(empty($uid)) $uid = getOpuser();
			if(empty($table))
				self::$data = makeOne(\model\user::class)->getPowersByUid($uid); 
			else
				self::$data = makeOne(\model\user::class)->getPowersByUid($uid, $table); 
		    $_SESSION['powerData'] = self::$data;
        }
        return self::$data;
    }
    /**
     * 编码判断
     * @param string $code
     * @return bool
     */
    public static function checkCode($code){
        self::init();
 		if(!isset(self::$data[$code]) ){
 		    //self::error(sprintf("[%s] %s", $code, lg("权限模块不存在")));
			//throw new \Exception( sprintf("[%s] %s", $code, lg("权限模块不存在")) );
			return false;
 		}
 		return true;
    }
    
    /**
     * isAdmin
     * @return string
     */
    public static function isAdmin(){
        self::init();
        return self::$data['isAdmin'];
    }
    
    /**
     * 取值
     * @params array $codes;
     * @return string
     */
    public static function getIds($codes,$field){
        self::init();
        if(is_string($codes)) $codes = explode(',',$codes);
        $ids = '';
        if($codes){
            foreach ($codes as $code){
                if(isset(self::$data[$code])){
                    if($ids!='') $ids .= ',';
                    $ids.= self::$data[$code][$field];
                }
            }
        }
        return mergeIds($ids,'');
   }
    
    /**
     * 取指定模块的 属性 约束
     * @return string
     */
    public static function fields($code){
        return self::getIds($code,'prl_fields');
    }
    
    /**
     * 取指定模块的 属性 的值
     * @return string
     */
    public static function fieldval($code,$name){
        $fields = ','.self::getIds($code,'prl_fields').',';
        preg_match('/,'.$name.':([A-Za-z0-9]+),/',$fields,$m);
        if(isset($m[1])){
            return $m[1];
        }else{
            return '';
        }
    }
    /**
     * 判断指定模块的 属性 的值是否存在
     * @return string
     */
    public static function fieldhas($code,$name){
		if(self::isAdmin()) return true;
        $fields = ','.self::getIds($code,'prl_fields').',';
        preg_match('/,('.$name.')[:,]/',$fields,$m);
        return isset($m[1]);
    }
    
    /**
     * 取指定模块的 品名 约束
     * @return string
     */
    public static function cates($code, $id = null){
		self::checkCode($code);
		$ids = self::getIds($code,'prl_cates_view');
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    public static function catesView($code, $id = null){
		self::checkCode($code);
		$ids = self::getIds($code,'prl_cates_view');
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    public static function catesAdd($code, $id = null){
		self::checkCode($code);
		$ids = self::getIds($code,'prl_cates_add');
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    public static function catesEdit($code, $id = null){
		self::checkCode($code);
		$ids = self::getIds($code,'prl_cates_edit');
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    public static function catesDelete($code, $id = null){
		self::checkCode($code);
		$ids = self::getIds($code,'prl_cates_delete');
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    public static function catesImport($code, $id = null){
		self::checkCode($code);
		$ids = self::getIds($code,'prl_cates_import');
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    public static function catesExport($code, $id = null){
		self::checkCode($code);
		$ids = self::getIds($code,'prl_cates_export');
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    public static function catesDone($code, $id = null){
		self::checkCode($code);
		$ids = self::getIds($code,'prl_cates_done');
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    public static function catesCheck1($code, $id = null){
		self::checkCode($code);
		$ids = self::getIds($code,'prl_cates_check1');
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    public static function catesCheck2($code, $id = null){
		self::checkCode($code);
		$ids = self::getIds($code,'prl_cates_check2');
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    public static function catesCheck3($code, $id = null){
		self::checkCode($code);
		$ids = self::getIds($code,'prl_cates_check3');
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }

    
    /**
     * 取指定模块的 指定品名的 产品参数 约束
     * @return string
     */
    public static function params($code,$cate,$id = null){
        self::checkCode($code);
		if($id && empty(self::$data[$code]['params'])) return true;
        if(isset(self::$data[$code]['params'][$cate])){
			$ids = self::$data[$code]['params'][$cate];
			if($id) return $ids == '' || self::hasval($ids, $id);
			return $ids;
        }else{
            return '';
		}
    }
    
    /**
     * 取指定模块的 国际大车型 约束
     * @return string
     */
    public static function makes($code, $id = null){
        self::checkCode($code);
		$ids = self::$data[$code]['prl_makes'];
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    /**
     * 取指定模块的 中国大车型 约束
     * @return string
     */
    public static function cnmakes($code, $id = null){
        self::checkCode($code);
		$ids = self::$data[$code]['prl_cnmakes'];
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    /**
     * 取指定模块的 号码品牌 约束
     * @return string
     */
    public static function factorys($code, $id = null){
        self::checkCode($code);
		$ids = self::$data[$code]['prl_factorys'];
		if($id) return $ids == '' || self::hasval($ids, $id);
        return $ids;
    }
    
    /**
     * 取指定模块的 数据版本 约束
     * @return string
     */
    public static function vers($code){
        self::checkCode($code);
        return self::$data[$code]['prl_vers'];
    }
    
    /**
     * 取指定模块的 区域 约束
     * @return string
     */
    public static function areas($code){
        self::checkCode($code);
        return self::$data[$code]['prl_areas'];
    }
    
    /**
     * 取指定模块的 用户 约束
     * @return string
     */
    public static function userIds($code){
        self::checkCode($code);
        return self::$data[$code]['userIds'];
    }
    
    /**
     * 取指定模块的 用户 约束
     * @return string
     */
    public static function userWhere($code){
        self::checkCode($code);
        return self::$data[$code]['userWhere'];
    }
    
    /**
     * 取指定模块的 用户 约束
     * @return string
     */
    public static function userSqlWhere($code){
        self::checkCode($code);
        return self::$data[$code]['userSqlWhere'];
    }

    
    /**
     * 取指定模块的 有哪些用户有这个权限
     * @return string
     */
    public static function getUserIdByPwcode($code){
        return makeOne(\model\user::class)->getUserIdByPwcode($code); 
    }

	public static function hasval($vals, $id)
	{
		$idArr = explode(',', $vals);
		return in_array($id, $idArr);
	}

    /**
     * 取指定模块的 国家 约束
     * @return string
     */
    public static function countrys($code){
        self::checkCode($code);
        return self::$data[$code]['prl_countrys'];
    }

}