<?php
class Auth extends BaseCode {

  function __construct(){
    parent::__construct();

    $this->DB->query_record = false; //query log 기록 금지

    $this->DB->tableExists(TB_auth_manage);
  }

  /** 권한저장
   * @param $cate_area : 권한범위
   * @param $cate_id : 권한 기능(메뉴)
   * @param $auth_area : 권한 그룹
   * @param $auth_target : 권한 대상
   * @param $auth : 권한
   * @return bool
   */
  public function putAuth( $cate_area, $cate_id, $auth_area, $auth_target, $auth ){
    $sql_row = Array(
      "cate_area"  => $cate_area?:"",
      "cate_id"    => $cate_id?:"",
      "auth_area"  => $auth_area?:"",
      "auth_target"=> $auth_target?:"",
      "auth"       => $auth?:"",
      "reg_date"   => $this->DB->sqleval("getdate()"),
      "mod_date"   => $this->DB->sqleval("getdate()"),
      "mod_id"     => $GLOBALS['_Umem']['member_id']?:"",
    );

    return $this->DB->insert(TB_auth_manage, $sql_row);
  }

  /** 권한수정
   * @param $cate_area : 권한범위
   * @param $cate_id : 권한 기능(메뉴)
   * @param $auth_area : 권한 그룹
   * @param $auth_target : 권한 대상
   * @param $auth : 권한
   * @param string $old_cate_id : 수정할 id
   * @return bool
   */
  public function setAuth( $cate_area, $cate_id, $auth_area, $auth_target, $auth, $old_cate_id="" ){
    $sql_row = Array(
      "auth" => $auth?:"",
      "mod_date"  => $this->DB->sqleval("getdate()"),
      "mod_id"    => $GLOBALS['_Umem']['member_id']?:"",
    );
    if( $old_cate_id && $cate_id != $old_cate_id ){
      $sql_row['cate_id'] = $cate_id;
    }

    $where = new DB_where("and");
    $where->add("cate_area = ?", $cate_area);
    $where->add("cate_id = ?", $old_cate_id?:$cate_id);
    $where->add("auth_area = ?", $auth_area);
    $where->add("auth_target = ?", $auth_target);

    $wqry = $where->get_where();
    $whereqry = $wqry['qry'];
    $whererow = $wqry['val'];

    $ins_sql_row = Array(
      "cate_area"  => $cate_area?:"",
      "cate_id"    => $cate_id?:"",
      "auth_area"  => $auth_area?:"",
      "auth_target"=> $auth_target?:"",
      "auth"       => $auth?:"",
      "reg_date"   => $this->DB->sqleval("getdate()"),
      "mod_date"   => $this->DB->sqleval("getdate()"),
      "mod_id"     => $GLOBALS['_Umem']['member_id']?:"",
    );

    return $this->DB->insertupdate(TB_auth_manage, $ins_sql_row, $sql_row, $whereqry, $whererow);

//    $sql = "select count(*) from ".TB_auth_manage." where {$whereqry}";
//    $cnt = $this->DB->queryFirstField($sql, $whererow);
//
//    if( $cnt ){
//      return $this->DB->update(TB_auth_manage, $sql_row, $whereqry, $whererow);
//    }else{
//      return $this->putAuth($cate_area, $cate_id, $auth_area, $auth_target, $auth);
//    }
  }

  /* 주석은 시간날때.. 하지만 언제나 시간은 없지
   * 권한추가
   * */
  public function addAuth( $cate_area, $cate_id, $auth_area, $auth_target, $auth ){
    $auth = (int)$auth;
    if( $auth > 7 || $auth < 0 ) return false;

    return $this->setAuth( $cate_area, $cate_id, $auth_area, $auth_target, $this->DB->sqleval("auth | {$auth}") );
  }

  /*
   * 권한제거
   * */
  public function remAuth( $cate_area, $cate_id, $auth_area, $auth_target, $auth ){
    $auth = (int)$auth;
    if( $auth > 7 || $auth < 0 ) return false;

    return $this->setAuth( $cate_area, $cate_id, $auth_area, $auth_target, $this->DB->sqleval("auth & ".(7 ^ $auth)) );
  }

  /*
   * 권한삭제
   * */
  public function delAuth( $cate_area, $cate_id, $auth_area="", $auth_target="" ){
    $where = new DB_where("and");
    $where->add("cate_area = ?", $cate_area);
    $where->add("cate_id = ?", $cate_id);
    if( $auth_area ){
      $where->add("auth_area = ?", $auth_area);
    }
    if( $auth_target ){
      $where->add("auth_target = ?", $auth_target);
    }

    $wqry = $where->get_where();
    $whereqry = $wqry['qry'];
    $whererow = $wqry['val'];

    return $this->DB->delete(TB_auth_manage, $whereqry, $whererow);
  }

  /**
   * @param $cate_area
   * @param $cate_id
   * @param string $auth_target
   * @return int
   */
  public function getAuthList( $cate_area="" ){
    $where = new DB_where("and");
    if( $cate_area ){
      $where->add("cate_area = ?", $cate_area);
    }
    $wqry = $where->get_where();
    $whereqry = $wqry['qry'];
    $whererow = $wqry['val'];

    $sql = "select cate_id, auth_area, auth_target, auth from ".TB_auth_manage." where {$whereqry}";
    $rst = $this->DB->qry($sql, $whererow);
    if( $rst ) {
      $rows = array();
      while ($row = $this->DB->fetch_array($rst)) {
        $rows[$row['cate_id']][$row['auth_area']][$row['auth_target']] = $this->getAuthToRow($row['auth']);
      }

      return $rows;
    }
    return $rst;
  }

  /** 회원권한조회 - 회원이 가진 (현메뉴)에서 가진 권한값 리턴
   * @param $cate_area : 권한범위
   * @param $cate_id : 권한 기능(메뉴)
   * @param string $auth_target : member_id, //Todo: 그룹권한만 확인하는 내용은 존재하지 않음
   * @return int
   */
  public function getAuth( $cate_area, $cate_id, $auth_target="" ){
    if( !$auth_target ){
      $mem = $GLOBALS['_Umem'];
      $auth_target = isset($mem['member_id'])?$mem['member_id']:"";
    }else{
      $mobj = new Member();
      $mem = $mobj->getMember($auth_target);
    }
    if( !isset($mem) || !$mem || !isset($mem['member_id']) || !$mem['member_id'] ){
      if( !is_array($mem) ){
        $mem = array();
      }
      $mem['member_auth'] = "Y"; //비회원
    }

    if( $mem['member_auth'] == 'SA' ) return 7; //슈퍼관리자는 무조건 Ok

    $where = new DB_where("and");
    $where->add("cate_area = ?", $cate_area);
    $where->add("cate_id = ?", $cate_id);
    $subwhere = $where->sub_where("or");

    $subwhere2 = $subwhere->sub_where("and");
    $subwhere2->add("auth_area = ?","G");
    $subwhere2->add("auth_target = ?",$mem['member_auth']);

    $subwhere3 = $subwhere->sub_where("and");
    $subwhere3->add("auth_area = ?","M");
    $subwhere3->add("auth_target = ?",$mem['member_id']);

    $wqry = $where->get_where();
    $whereqry = $wqry['qry'];
    $whererow = $wqry['val'];

    $sql = "select auth from ".TB_auth_manage." where {$whereqry}";
    $rows = $this->DB->query($sql, $whererow);
    $auth = 0;
    foreach( (array)$rows as $row ){
      $auth = $auth | $row['auth'];
    }

    //권한 제거 가 존재한다면(예: 레벨권한, 그룹권한으로 권한을 획득했지만 해당 인원만 쓰기 금지.)... 아래 로직을 적절하게 적용한다.
    // $dauth <-- 제거할 권한(예: 7->모든 권한 제거, 4->수정삭제권한 제거, 2->쓰기권한제거, 1->읽기권한 제거)
    // $auth = $auth & ~$dauth;
    return $auth;
  }

  /** 권한 Normalize
   * @param $auth
   * @return int
   */
  public function normalAuth($auth){
    $auth = strtolower($auth);
    switch( true ){
      case in_array( $auth, Array("r", "read", "1", 1) ) :
        $auth = 1; break;

      case in_array( $auth, Array("w", "write", "put", "2", 2) ) :
        $auth = 2; break;

      case in_array( $auth, Array("u", "up", "update", "m", "mod", "modify", "set", "d", "del", "delete", "4", 4) ) :
        $auth = 4; break;

      default :
        $auth = 0;
    }
    return $auth;
  }

  /** 권한확인
   * @param $auth : 권한
   * @param $cate_area : 권한범위
   * @param $cate_id : 권한 기능(메뉴)
   * @param string $auth_target : member_id, //Todo: 그룹권한만 확인하는 내용은 존재하지 않음
   * @return int
   */
  public function hasAuth( $auth, $cate_area, $cate_id, $auth_target="" ){
    $allow = $this->getAuth($cate_area, $cate_id, $auth_target);
    $auth = $this->normalAuth($auth);
    return $auth & $allow;
  }

  /** 권한 get num -> row
   * @param $auth : 권한
   * @return array
   */
  public function getAuthToRow($auth){
    $arow = Array();

    $arow["R"] = (bool)($auth & 1);
    $arow["W"] = (bool)($auth & 2);
    $arow["D"] = (bool)($auth & 4);

    return $arow;
  }

  /*
   * 권한 get row(string) -> num
   * */
  public function getAuthToNum($read, $write, $delete){
    return ($read?1:0)+($write?2:0)+($delete?4:0);
  }


  /** 해당 권한을 가진 id get
   * @param $row : 권한 배열
   * @param $auth : 찾아낼 권한
   * @return array
   */
  public function getHasAuthRow( $row, $auth ){
    $auth = $this->normalAuth($auth);
    $rerow = array();
    foreach( (array)$row as $k => $v ){
      if( $v & $auth ){
        $rerow[] = $k;
      }
    }
    return $rerow;
  }
}