#!/usr/bin/php -q

<?php
error_reporting(E_ALL);

/*==========================================================================================================================
PHP 경로찾기
    [#] whereis php
찾아진 경로를 현 소스의 맨 위 코드에 반영, 일반적으로 수정할 일이 없음   예)#!/usr/bin/my_php -q
==========================================================================================================================*/

/*==========================================================================================================================
필수 설정값:
==========================================================================================================================*/
$g4_config_file = './g4';          // g4 에서 사용하는 config.php 파일의 경로를 현재 경로부터 기재
$_SERVER['SERVER_PORT'] = 80;       // apache 가 사용하는 포트

//==========================================================================================================================
// g4_import_run.php 를 브라우저에서 수행하면 브라우저가 뻗는 경우가 있으므로 직접 Shell 에서 실행하기 위함입니다
// 아래의 소스 부분은 특별히 수정할 필요가 없으나
// 행여 불필요한 소스가 있다면 삭제하셔도 됩니다
// 10분만에 작업한 것이라 세세하게 작업하지 못하였습니다

// g4_import.php 에 기재된 내용과 동일하지만 혹여 두번실행할 까봐 내용을 옮겨 둡니다

// 이 프로그램은 그누보드5 설치 후 바로 실행하셔야만 합니다.
// 만약 그누보드5 사이트를 운영 중에 이 프로그램을 실행하시면 DB 데이터가 망실되거나 데이터의 오류가 발생할 수 있습니다.
// 또한 중복해서 실행하실 경우에도 DB 데이터의 오류가 발생할 수 있으니 반드시 한번만 실행해 주십시오.


// 실행방법은 현재의 파일이 있는곳까지 shell 로 이동한 후 ①실행권한 부여, ②실행  하면 됩니다
// 완료여부는 그누보드4 DB 데이터 이전 완료 라는 메세지가 보이면 됩니다
// [#] chmod 700 ./g4_to_g5.php
// [#] php ./g4_to_g5.php
//==========================================================================================================================



















/*******************************************************************************
** 공통 변수, 상수, 코드
*******************************************************************************/
error_reporting(E_ALL);


if (!defined('G5_SET_TIME_LIMIT')) define('G5_SET_TIME_LIMIT', 0);
set_time_limit(G5_SET_TIME_LIMIT);
//set_time_limit(0);

$_SERVER['SERVER_NAME'] = '';       // 빈값 유지
$_SERVER['REQUEST_URI'] = '';       // 빈값 유지

//==========================================================================================================================
// extract($_GET); 명령으로 인해 page.php?_POST[var1]=data1&_POST[var2]=data2 와 같은 코드가 _POST 변수로 사용되는 것을 막음
// 081029 : letsgolee 님께서 도움 주셨습니다.
//--------------------------------------------------------------------------------------------------------------------------
$ext_arr = array ('PHP_SELF', '_ENV', '_GET', '_POST', '_FILES', '_SERVER', '_COOKIE', '_SESSION', '_REQUEST',
                  'HTTP_ENV_VARS', 'HTTP_GET_VARS', 'HTTP_POST_VARS', 'HTTP_POST_FILES', 'HTTP_SERVER_VARS',
                  'HTTP_COOKIE_VARS', 'HTTP_SESSION_VARS', 'GLOBALS');
$ext_cnt = count($ext_arr);
for ($i=0; $i<$ext_cnt; $i++) {
    // POST, GET 으로 선언된 전역변수가 있다면 unset() 시킴
    if (isset($_GET[$ext_arr[$i]]))  unset($_GET[$ext_arr[$i]]);
    if (isset($_POST[$ext_arr[$i]])) unset($_POST[$ext_arr[$i]]);
}
//==========================================================================================================================
function g5_path()
{
    $result['path'] = str_replace('\\', '/', dirname(__FILE__));
    $tilde_remove = preg_replace('/^\/\~[^\/]+(.*)$/', '$1', $_SERVER['SCRIPT_NAME']);
    $document_root = str_replace($tilde_remove, '', $_SERVER['SCRIPT_FILENAME']);
    $pattern = '/' . preg_quote($document_root, '/') . '/i';
    $root = preg_replace($pattern, '', $result['path']);
    $port = $_SERVER['SERVER_PORT'] != 80 ? ':'.$_SERVER['SERVER_PORT'] : '';
    $http = 'http' . ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']=='on') ? 's' : '') . '://';
    $user = str_replace(preg_replace($pattern, '', $_SERVER['SCRIPT_FILENAME']), '', $_SERVER['SCRIPT_NAME']);
    $host = isset($_SERVER['HTTP_HOST']) ? $_SERVER['HTTP_HOST'] : $_SERVER['SERVER_NAME'];
    if(isset($_SERVER['HTTP_HOST']) && preg_match('/:[0-9]+$/', $host))
        $host = preg_replace('/:[0-9]+$/', '', $host);
    $host = preg_replace("/[\<\>\'\"\\\'\\\"\%\=\(\)\/\^\*]/", '', $host);
    $result['url'] = $http.$host.$port.$user.$root;
    return $result;
}

$g5_path = g5_path();

include_once($g5_path['path'].'/config.php');   // 설정 파일

unset($g5_path);


// multi-dimensional array에 사용자지정 함수적용
function array_map_deep($fn, $array)
{
    if(is_array($array)) {
        foreach($array as $key => $value) {
            if(is_array($value)) {
                $array[$key] = array_map_deep($fn, $value);
            } else {
                $array[$key] = call_user_func($fn, $value);
            }
        }
    } else {
        $array = call_user_func($fn, $array);
    }

    return $array;
}


// SQL Injection 대응 문자열 필터링
function sql_escape_string($str)
{
    if(defined('G5_ESCAPE_PATTERN') && defined('G5_ESCAPE_REPLACE')) {
        $pattern = G5_ESCAPE_PATTERN;
        $replace = G5_ESCAPE_REPLACE;

        if($pattern)
            $str = preg_replace($pattern, $replace, $str);
    }
    $str = call_user_func('addslashes', $str);
    return $str;
}


//==============================================================================
// SQL Injection 등으로 부터 보호를 위해 sql_escape_string() 적용
//------------------------------------------------------------------------------
// magic_quotes_gpc 에 의한 backslashes 제거
if (get_magic_quotes_gpc()) {
    $_POST    = array_map_deep('stripslashes',  $_POST);
    $_GET     = array_map_deep('stripslashes',  $_GET);
    $_COOKIE  = array_map_deep('stripslashes',  $_COOKIE);
    $_REQUEST = array_map_deep('stripslashes',  $_REQUEST);
}

// sql_escape_string 적용
$_POST    = array_map_deep(G5_ESCAPE_FUNCTION,  $_POST);
$_GET     = array_map_deep(G5_ESCAPE_FUNCTION,  $_GET);
$_COOKIE  = array_map_deep(G5_ESCAPE_FUNCTION,  $_COOKIE);
$_REQUEST = array_map_deep(G5_ESCAPE_FUNCTION,  $_REQUEST);
//==============================================================================


// PHP 4.1.0 부터 지원됨
// php.ini 의 register_globals=off 일 경우
@extract($_GET);
@extract($_POST);
@extract($_SERVER);

$config = array();
$member = array();
$board  = array();
$group  = array();
$g5     = array();


$dbconfig_file = G5_DATA_PATH.'/'.G5_DBCONFIG_FILE;
if (file_exists($dbconfig_file)) {
    include_once($dbconfig_file);
    include_once(G5_LIB_PATH.'/common.lib.php');    // 공통 라이브러리

    $connect_db = sql_connect(G5_MYSQL_HOST, G5_MYSQL_USER, G5_MYSQL_PASSWORD) or die('MySQL Connect Error!!!');
    $select_db  = sql_select_db(G5_MYSQL_DB, $connect_db) or die('MySQL DB Error!!!');

    // mysql connect resource $g5 배열에 저장 - 명랑폐인님 제안
    $g5['connect_db'] = $connect_db;

    sql_set_charset('utf8', $connect_db);
    if(defined('G5_MYSQL_SET_MODE') && G5_MYSQL_SET_MODE) sql_query("SET SESSION sql_mode = ''");
    if (defined('G5_TIMEZONE')) sql_query(" set time_zone = '".G5_TIMEZONE."'");
}

@ini_set("url_rewriter.tags",""); // 링크에 PHPSESSID가 따라다니는것을 무력화함 (해뜰녘님께서 알려주셨습니다.)


// common.php 파일을 수정할 필요가 없도록 확장합니다.
$extend_file = array();
$tmp = dir(G5_EXTEND_PATH);
while ($entry = $tmp->read()) {
    // php 파일만 include 함
    if (preg_match("/(\.php)$/i", $entry))
        $extend_file[] = $entry;
}

if(!empty($extend_file) && is_array($extend_file)) {
    natsort($extend_file);

    foreach($extend_file as $file) {
        include_once(G5_EXTEND_PATH.'/'.$file);
    }
}
unset($extend_file);

include_once(G5_LIB_PATH.'/connect.lib.php');
$begin_time = get_microtime();

$g4_config_file = preg_replace('#/config.php$#i', '', $g4_config_file).'/config.php';

$is_euckr = false;



// g4의 confing.php
require($g4_config_file);

if(preg_replace('/[^a-z]/', '', strtolower($g4['charset'])) == 'euckr')
    $is_euckr = true;


//=========== 테이블 복사 시작 ===================================================================
// member table 복사
$columns = sql_field_names($g5['member_table']);

$sql = " select * from {$g4['member_table']} ";
$result = sql_query($sql);
for($i=0; $row=sql_fetch_array($result); $i++) {
    if($is_euckr)
        $row = array_map('iconv_utf8', $row);

    // 중복체크
    $sql2 = " select count(*) as cnt from {$g5['member_table']} where mb_id = '{$row['mb_id']}' ";
    $row2 = sql_fetch($sql2);
    if($row2['cnt'])
        continue;

    $comma = '';
    $sql_common = '';

    foreach($row as $key=>$val) {
        if($key == 'mb_no')
            continue;

        if(!in_array($key, $columns))
            continue;

        $sql_common .= $comma . " $key = '".addslashes($val)."' ";

        $comma = ',';
    }
    sql_query(" INSERT INTO {$g5['member_table']} SET $sql_common ");
}

echo 'member table 복사'.PHP_EOL;
unset($columns);
unset($fiels);

// point table 복사
$sql = " select * from {$g4['point_table']} ";
$result = sql_query($sql);

for($i=0; $row=sql_fetch_array($result); $i++) {
    if($is_euckr)
        $row = array_map('iconv_utf8', $row);

    $comma = '';
    $sql_common = '';

    foreach($row as $key=>$val) {
        if($key == 'po_id')
            continue;

        $sql_common .= $comma . " $key = '".addslashes($val)."' ";

        $comma = ',';
    }
    sql_query(" INSERT INTO {$g5['point_table']} SET $sql_common ");
}
echo 'point table 복사'.PHP_EOL;

// login table 복사
$sql = " select * from {$g4['login_table']} ";
$result = sql_query($sql);
for($i=0; $row=sql_fetch_array($result); $i++) {
    if($is_euckr)
        $row = array_map('iconv_utf8', $row);

    // 중복체크
    $sql2 = " select count(*) as cnt from {$g5['login_table']} where lo_ip = '{$row['lo_ip']}' ";
    $row2 = sql_fetch($sql2);
    if($row2['cnt'])
        continue;

    $comma = '';
    $sql_common = '';

    foreach($row as $key=>$val) {
        $sql_common .= $comma . " $key = '".addslashes($val)."' ";

        $comma = ',';
    }

    sql_query(" INSERT INTO {$g5['login_table']} SET $sql_common ");
}
echo 'login table 복사'.PHP_EOL;

// visit table 복사
$sql = " select * from {$g4['visit_table']} ";
$result = sql_query($sql);

// g5_visit 테이블 초기화
sql_query(" delete from {$g5['visit_table']} ");

for($i=0; $row=sql_fetch_array($result); $i++) {
    if($is_euckr)
        $row = array_map('iconv_utf8', $row);

    // 중복체크
    /*
    $sql2 = " select count(*) as cnt from {$g5['visit_table']} where vi_ip = '{$row['vi_ip']}' and vi_date = '{$row['vi_date']}' ";
    $row2 = sql_fetch($sql2);
    if($row2['cnt'])
        continue;
    */

    $comma = '';
    $sql_common = '';

    foreach($row as $key=>$val) {
        $sql_common .= $comma . " $key = '".addslashes($val)."' ";

        $comma = ',';
    }

    sql_query(" INSERT INTO {$g5['visit_table']} SET $sql_common ");
}
echo 'visit table 복사'.PHP_EOL;

// visit sum table 복사
$sql = " select * from {$g4['visit_sum_table']} ";
$result = sql_query($sql);

// g5_visit_sub 테이블 초기화
sql_query(" delete from {$g5['visit_sum_table']} ");

for($i=0; $row=sql_fetch_array($result); $i++) {
    if($is_euckr)
        $row = array_map('iconv_utf8', $row);

    // 중복체크
    /*
    $sql2 = " select count(*) as cnt from {$g5['visit_sum_table']} where vs_date = '{$row['vs_date']}' ";
    $row2 = sql_fetch($sql2);
    if($row2['cnt'])
        continue;
    */

    $comma = '';
    $sql_common = '';

    foreach($row as $key=>$val) {
        $sql_common .= $comma . " $key = '".addslashes($val)."' ";

        $comma = ',';
    }

    sql_query(" INSERT INTO {$g5['visit_sum_table']} SET $sql_common ");
}
echo 'visit sum table 복사'.PHP_EOL;

// group table 복사
$columns = sql_field_names($g5['group_table']);

$sql = " select * from {$g4['group_table']} ";
$result = sql_query($sql);
for($i=0; $row=sql_fetch_array($result); $i++) {
    if($is_euckr)
        $row = array_map('iconv_utf8', $row);

    // 중복체크
    $sql2 = " select count(*) as cnt from {$g5['group_table']} where gr_id = '{$row['gr_id']}' ";
    $row2 = sql_fetch($sql2);
    if($row2['cnt'])
        continue;

    $comma = '';
    $sql_common = '';

    foreach($row as $key=>$val) {
        if(!in_array($key, $columns))
            continue;

        $sql_common .= $comma . " $key = '".addslashes($val)."' ";

        $comma = ',';
    }

    sql_query(" INSERT INTO {$g5['group_table']} SET $sql_common ");
}

echo 'group table 복사'.PHP_EOL;
unset($columns);
unset($fiels);

// board 복사
$columns = sql_field_names($g5['board_table']);

$sql = " select * from {$g4['board_table']} ";
$result = sql_query($sql);
for($i=0; $row=sql_fetch_array($result); $i++) {
    if($is_euckr)
        $row = array_map('iconv_utf8', $row);

    // 중복체크
    $sql2 = " select count(*) as cnt from {$g5['board_table']} where bo_table = '{$row['bo_table']}' ";
    $row2 = sql_fetch($sql2);
    if($row2['cnt'])
        continue;

    $comma = '';
    $sql_common = '';

    foreach($row as $key=>$val) {
        if(!in_array($key, $columns))
            continue;

        $sql_common .= $comma . " $key = '".addslashes($val)."' ";

        $comma = ',';
    }

    sql_query(" INSERT INTO {$g5['board_table']} SET $sql_common ");

    // 게시판 테이블 생성
    $bo_table = $row['bo_table'];
    $file = file(G5_ADMIN_PATH.'/sql_write.sql');
    $sql = implode($file, "\n");

    $create_table = $g5['write_prefix'] . $bo_table;

    $source = array('/__TABLE_NAME__/', '/;/');
    $target = array($create_table, '');
    $sql = preg_replace($source, $target, $sql);

    // 게시글 복사
    if(sql_query($sql, FALSE)) {
        $write_table = $g4['write_prefix'].$bo_table;
        $columns2 = sql_field_names($create_table);

        $sql3 = " select * from $write_table ";
        $result3 = sql_query($sql3);

        for($k=0; $row3=sql_fetch_array($result3); $k++) {
            if($is_euckr)
                $row3 = array_map('iconv_utf8', $row3);

            $comma3 = '';
            $sql_common3 = '';

            foreach($row3 as $key=>$val) {
                if(!in_array($key, $columns2))
                    continue;

                $sql_common3 .= $comma3 . " $key = '".addslashes($val)."' ";

                $comma3 = ',';
            }

            // 첨부파일개수
            $wr_id = $row3['wr_id'];
            $sql4 = " select count(*) as cnt from {$g4['board_file_table']} where bo_table = '$bo_table' and wr_id = '$wr_id' ";
            $row4 = sql_fetch($sql4);

            $sql_common3 .= " , wr_file = '{$row4['cnt']}' ";

            sql_query(" INSERT INTO $create_table SET $sql_common3 ");
        }

        echo ''.str_replace(G5_TABLE_PREFIX.'write_', '', $create_table).' 게시글 복사';
    }
}

unset($columns);
unset($fiels);

// 그외 테이블 복사
$tables = array('board_file', 'board_new', 'board_good', 'mail', 'memo', 'group_member', 'auth', 'popular', 'poll', 'poll_etc', 'scrap');

foreach($tables as $table) {
    $columns = sql_field_names($g5[$table.'_table']);

    $src_table = $g4[$table.'_table'];
    $dst_table = $g5[$table.'_table'];
    $sql = " select * from $src_table ";
    $result = sql_query($sql);
    for($i=0; $row=sql_fetch_array($result); $i++) {
        if($is_euckr)
            $row = array_map('iconv_utf8', $row);

        $comma = '';
        $sql_common = '';

        foreach($row as $key=>$val) {
            if(!in_array($key, $columns))
                continue;

            $sql_common .= $comma . " $key = '".addslashes($val)."' ";

            $comma = ',';
        }

        $result2 = sql_query(" INSERT INTO $dst_table SET $sql_common ", false);
        if(!$result2)
            continue;
    }
    echo ''.$table.' table 복사'.PHP_EOL;
}

unset($columns);
unset($fiels);

echo ''.PHP_EOL;
echo '======================================================================'.PHP_EOL;
echo '그누보드4 DB 데이터 이전 완료'.PHP_EOL;
echo '======================================================================';