<?php
if (!defined('_GNUBOARD_'))
  exit;

function get_skin_select($skin_gubun, $id, $name, $selected = '', $event = '')
{
  global $config;
  $skins = [];
  if (defined('G5_THEME_PATH') && $config['cf_theme']) {
    $dirs = get_skin_dir($skin_gubun, G5_THEME_PATH . '/' . G5_SKIN_DIR);
    if (!empty($dirs)) {
      foreach ($dirs as $dir) {
        $skins[] = "theme/{$dir}";
      }
    }
  }

  $skins = array_merge($skins, get_skin_dir($skin_gubun));
  $str = "<select id=\"$id\" name=\"$name\" $event>\n";
  for ($i = 0; $i < count($skins); $i++) {
    if ($i == 0)
      $str .= "<option value=\"\">선택</option>";
    if (preg_match('#^theme/(.+)$#', $skins[$i], $match))
      $text = "(테마) {$match[1]}";
    else
      $text = $skins[$i];

    $str .= option_selected($skins[$i], $selected, $text);
  }
  $str .= "</select>";
  return $str;
}

// 모바일 스킨디렉토리를 SELECT 형식으로 얻음
function get_mobile_skin_select($skin_gubun, $id, $name, $selected = '', $event = '')
{
  global $config;
  $skins = [];
  if (defined('G5_THEME_PATH') && $config['cf_theme']) {
    $dirs = get_skin_dir($skin_gubun, G5_THEME_MOBILE_PATH . '/' . G5_SKIN_DIR);
    if (!empty($dirs)) {
      foreach ($dirs as $dir) {
        $skins[] = "theme/{$dir}";
      }
    }
  }

  $skins = array_merge($skins, get_skin_dir($skin_gubun, G5_MOBILE_PATH . '/' . G5_SKIN_DIR));

  $str = "<select id=\"$id\" name=\"$name\" $event>\n";
  for ($i = 0; $i < count($skins); $i++) {
    if ($i == 0)
      $str .= "<option value=\"\">선택</option>";
    if (preg_match('#^theme/(.+)$#', $skins[$i], $match))
      $text = "(테마) {$match[1]}";
    else
      $text = $skins[$i];

    $str .= option_selected($skins[$i], $selected, $text);
  }
  $str .= "</select>";
  return $str;
}


// 스킨경로를 얻는다
function get_skin_dir($skin, $skin_path = G5_SKIN_PATH)
{
  global $g5;
  $result_array = [];
  $dirname = implode(DIRECTORY_SEPARATOR, [$skin_path, $skin, ""]);
  if (!is_dir($dirname))
    return;

  $handle = opendir($dirname);
  while ($file = readdir($handle)) {
    if ($file == '.' || $file == '..')
      continue;

    if (is_dir($dirname . $file))
      $result_array[] = $file;
  }
  closedir($handle);
  sort($result_array);

  return $result_array;
}

// 테마
function get_theme_dir()
{
  $result_array = [];

  $dirname = G5_PATH . '/' . G5_THEME_DIR . '/';
  $handle = opendir($dirname);
  while ($file = readdir($handle)) {
    if ($file == '.' || $file == '..')
      continue;

    if (is_dir($dirname . $file)) {
      $theme_path = $dirname . $file;
      if (is_file($theme_path . '/index.php') && is_file($theme_path . '/head.php') && is_file($theme_path . '/tail.php'))
        $result_array[] = $file;
    }
  }
  closedir($handle);
  natsort($result_array);

  return $result_array;
}

// 테마디렉토리를 SELECT 형식으로 얻음
function get_theme_select($id, $name, $selected = '', $event = '')
{
  global $config;

  $theme = [];
  $theme = array_merge($theme, get_theme_dir());

  $str = "<select id=\"$id\" name=\"$name\" $event>\n";
  for ($i = 0; $i < count($theme); $i++) {
    if ($i == 0)
      $str .= "<option value=\"\">-</option>";
    $text = $theme[$i];

    $str .= option_selected($theme[$i], $selected, $text);
  }
  $str .= "</select>";
  return $str;
}

// 테마정보
function get_theme_info($dir)
{
  $info = [];
  $path = implode(DIRECTORY_SEPARATOR, [G5_PATH, G5_THEME_DIR, $dir]);

  if (is_dir($path)) {
    $screenshot = $path . '/screenshot.png';
    if (is_file($screenshot)) {
      $size = @getimagesize($screenshot);

      if ($size[2] == 3)
        $screenshot_url = str_replace(G5_PATH, G5_URL, $screenshot);
    }

    $info['screenshot'] = $screenshot_url;

    $text = $path . '/readme.txt';
    if (is_file($text)) {
      $content = file($text, false);
      $content = array_map('trim', $content);

      preg_match('#^Theme Name:(.+)$#i', $content[0], $m0);
      preg_match('#^Theme URI:(.+)$#i', $content[1], $m1);
      preg_match('#^Maker:(.+)$#i', $content[2], $m2);
      preg_match('#^Maker URI:(.+)$#i', $content[3], $m3);
      preg_match('#^Version:(.+)$#i', $content[4], $m4);
      preg_match('#^Detail:(.+)$#i', $content[5], $m5);
      preg_match('#^License:(.+)$#i', $content[6], $m6);
      preg_match('#^License URI:(.+)$#i', $content[7], $m7);

      $info['theme_name'] = trim($m0[1]);
      $info['theme_uri'] = trim($m1[1]);
      $info['maker'] = trim($m2[1]);
      $info['maker_uri'] = trim($m3[1]);
      $info['version'] = trim($m4[1]);
      $info['detail'] = trim($m5[1]);
      $info['license'] = trim($m6[1]);
      $info['license_uri'] = trim($m7[1]);
    }

    if (!$info['theme_name'])
      $info['theme_name'] = $dir;
  }

  return $info;
}


// 테마설정 정보
function get_theme_config_value($dir, $key = '*')
{
  $tconfig = [];

  $theme_config_file = G5_PATH . '/' . G5_THEME_DIR . '/' . $dir . '/theme.config.php';
  if (is_file($theme_config_file)) {
    include($theme_config_file);

    if ($key == '*') {
      $tconfig = $theme_config;
    } else {
      $keys = array_map('trim', explode(',', $key));
      foreach ($keys as $v) {
        $tconfig[$v] = isset($theme_config[$v]) ? trim($theme_config[$v]) : '';
      }
    }
  }

  return $tconfig;
}

// 회원권한을 SELECT 형식으로 얻음
function get_member_level_select($name, $start_id = 0, $end_id = 10, $selected = "", $event = "")
{
  global $g5;

  $level_name[1] = "방문자";
  $level_name[2] = "멤버";
  $level_name[3] = "상위멤버";
  $level_name[10] = "운영자";

  $str = "\n<select id=\"{$name}\" name=\"{$name}\"";
  if ($event)
    $str .= " $event";
  $str .= ">\n";
  for ($i = $start_id; $i <= $end_id; $i++) {
    if (!$level_name[$i])
      continue;

    $str .= '<option value="' . $i . '"';
    if ($i == $selected)
      $str .= ' selected="selected"';
    $str .= ">{$level_name[$i]}&nbsp;&nbsp;</option>\n";
  }
  $str .= "</select>\n";
  return $str;
}

// 회원아이디를 SELECT 형식으로 얻음
function get_member_id_select($name, $level, $selected = "", $event = "")
{
  global $g5;

  $sql = " select mb_id from {$g5['member_table']} where mb_level >= '{$level}' ";
  $result = sql_query($sql);
  $str = '<select id="' . $name . '" name="' . $name . '" ' . $event . '><option value="">선택안함</option>';
  for ($i = 0; $row = sql_fetch_array($result); $i++) {
    $str .= '<option value="' . $row['mb_id'] . '"';
    if ($row['mb_id'] == $selected)
      $str .= ' selected';
    $str .= '>' . $row['mb_id'] . '</option>';
  }
  $str .= '</select>';
  return $str;
}

/* 2024.06.04 check */
// php8 버전 호환 권한 검사 함수
function auth_check_menu($auth, $sub_menu, $attr, $return = false)
{
  $check_auth = isset($auth[$sub_menu]) ? $auth[$sub_menu] : '';
  return auth_check($check_auth, $attr, $return);
}

// 권한 검사
function auth_check($auth, $attr, $return = false)
{
  global $is_admin;

  if ($is_admin == 'super')
    return;

  if (!trim($auth)) {
    $msg = '이 메뉴에는 접근 권한이 없습니다.\\n\\n접근 권한은 최고관리자만 부여할 수 있습니다.';
    if ($return)
      return $msg;
    else
      alert($msg);
  }

  $attr = strtolower($attr);

  if (!strstr($auth, $attr)) {
    if ($attr == 'r') {
      $msg = '읽을 권한이 없습니다.';
      if ($return)
        return $msg;
      else
        alert($msg);
    } else if ($attr == 'w') {
      $msg = '입력, 추가, 생성, 수정 권한이 없습니다.';
      if ($return)
        return $msg;
      else
        alert($msg);
    } else if ($attr == 'd') {
      $msg = '삭제 권한이 없습니다.';
      if ($return)
        return $msg;
      else
        alert($msg);
    } else {
      $msg = '속성이 잘못 되었습니다.';
      if ($return)
        return $msg;
      else
        alert($msg);
    }
  }
}


// 작업아이콘 출력
function icon($act, $link = '', $target = '_parent')
{
  global $g5;

  $img = array('입력' => 'insert', '추가' => 'insert', '생성' => 'insert', '수정' => 'modify', '삭제' => 'delete', '이동' => 'move', '그룹' => 'move', '보기' => 'view', '미리보기' => 'view', '복사' => 'copy');
  $icon = '<img src="' . G5_ADMIN_PATH . '/img/icon_' . $img[$act] . '.gif" title="' . $act . '">';
  if ($link)
    $s = '<a href="' . $link . '">' . $icon . '</a>';
  else
    $s = $icon;
  return $s;
}


// rm -rf 옵션 : exec(), system() 함수를 사용할 수 없는 서버 또는 win32용 대체
// www.php.net 참고 : pal at degerstrom dot com
function rm_rf($file)
{
  if (file_exists($file)) {
    if (is_dir($file)) {
      $handle = opendir($file);
      while ($filename = readdir($handle)) {
        if ($filename != '.' && $filename != '..')
          rm_rf($file . '/' . $filename);
      }
      closedir($handle);

      @chmod($file, G5_DIR_PERMISSION);
      @rmdir($file);
    } else {
      @chmod($file, G5_FILE_PERMISSION);
      @unlink($file);
    }
  }
}



// 출력순서
function order_select($fld, $sel = '')
{
  $s = '<select name="' . $fld . '" id="' . $fld . '">';
  for ($i = 1; $i <= 100; $i++) {
    $s .= '<option value="' . $i . '" ';
    if ($sel) {
      if ($i == $sel) {
        $s .= 'selected';
      }
    } else {
      if ($i == 50) {
        $s .= 'selected';
      }
    }
    $s .= '>' . $i . '</option>';
  }
  $s .= '</select>';

  return $s;
}

// 불법접근을 막도록 토큰을 생성하면서 토큰값을 리턴
function get_admin_token()
{
  $token = md5(uniqid(rand(), true));
  set_session('ss_admin_token', $token);

  return $token;
}

//input value 에서 xss 공격 filter 역할을 함 ( 반드시 input value='' 타입에만 사용할것 )
function get_sanitize_input($s, $is_html = false)
{
  if (!$is_html) {
    $s = strip_tags($s);
  }
  $s = htmlspecialchars($s, ENT_QUOTES, 'utf-8');
  return $s;
}

// POST로 넘어온 토큰과 세션에 저장된 토큰 비교
function check_admin_token()
{
  $token = get_session('ss_admin_token');
  set_session('ss_admin_token', '');

  if (!$token || !$_REQUEST['token'] || $token != $_REQUEST['token'])
    alert('올바른 방법으로 이용해 주십시오.', G5_URL);

  return true;
}

// 관리자 페이지 referer 체크
function admin_referer_check($return = false)
{
  $referer = trim($_SERVER['HTTP_REFERER']);
  if (!$referer) {
    $msg = '정보가 올바르지 않습니다.';

    if ($return)
      return $msg;
    else
      alert($msg, G5_URL);
  }

  $p = @parse_url($referer);
  $host = preg_replace('/:[0-9]+$/', '', $_SERVER['HTTP_HOST']);

  if ($host != $p['host']) {
    $msg = '올바른 방법으로 이용해 주십시오.';

    if ($return)
      return $msg;
    else
      alert($msg, G5_URL);
  }
}

// 접근 권한 검사
if (!$member['mb_id']) {
  goto_url(G5_BBS_URL . '/login.php?url=' . urlencode(G5_ADMIN_URL));
} else if ($is_admin != 'super') {
  $auth = [];
  $sql = " select au_menu, au_auth from {$g5['auth_table']} where mb_id = '{$member['mb_id']}' ";
  $result = sql_query($sql);
  for ($i = 0; $row = sql_fetch_array($result); $i++) {
    $auth[$row['au_menu']] = $row['au_auth'];
  }

  if (!$i) {
    goto_url(G5_URL);
  }
}

// 관리자의 아이피, 브라우저와 다르다면 세션을 끊고 관리자에게 메일을 보낸다.
$admin_key = md5($member['mb_datetime'] . $_SERVER['REMOTE_ADDR'] . $_SERVER['HTTP_USER_AGENT']);
if (get_session('ss_mb_key') !== $admin_key) {

  session_destroy();

  include_once(G5_LIB_PATH . '/mailer.lib.php');
  // 메일 알림
  mailer($member['mb_nick'], $member['mb_email'], $member['mb_email'], 'XSS 공격 알림', $_SERVER['REMOTE_ADDR'] . ' 아이피로 XSS 공격이 있었습니다.\n\n관리자 권한을 탈취하려는 접근이므로 주의하시기 바랍니다.\n\n해당 아이피는 차단하시고 의심되는 게시물이 있는지 확인하시기 바랍니다.\n\n' . G5_URL, 0);

  alert_close('정상적으로 로그인하여 접근하시기 바랍니다.');
}

@ksort($auth);

// 가변 메뉴
unset($auth_menu);
unset($menu);
$tmp = dir(G5_ADMIN_PATH);

$menu = [];

while ($entry = $tmp->read()) {
  if (preg_match('/(.*?)\.menu\.php$/', $entry, $m)) {
    include_once implode(DIRECTORY_SEPARATOR, [G5_ADMIN_PATH, $entry]);
  }
}

usort($menu, function ($a, $b) {
  return $a->order - $b->order;
});

$arr_query = [];
if (isset($sst))
  $arr_query[] = 'sst=' . $sst;
if (isset($sod))
  $arr_query[] = 'sod=' . $sod;
if (isset($sfl))
  $arr_query[] = 'sfl=' . $sfl;
if (isset($stx))
  $arr_query[] = 'stx=' . $stx;
if (isset($page))
  $arr_query[] = 'page=' . $page;
$qstr = implode("&amp;", $arr_query);

if (run_replace('safe_admin_add_script_boolean', false) === false) {
  $config['cf_analytics'] = '';
  $config['cf_add_script'] = '';
  $config['cf_add_meta'] = '';
}
