Files
Gnuboard5/install/install.function.php

477 lines
14 KiB
PHP

<?php
if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
if( ! function_exists('array_map_deep') ){
// 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;
}
}
if( ! function_exists('safe_install_string_check') ){
function safe_install_string_check( $str, $is_json=false ) {
$is_check = false;
if(preg_match('#\);(passthru|eval|pcntl_exec|exec|system|popen|fopen|fsockopen|file|file_get_contents|readfile|unlink|include|include_once|require|require_once)\s?#i', $str)) {
$is_check = true;
}
if(preg_match('#\$_(get|post|request)\s?\[.*?\]\s?\)#i', $str)){
$is_check = true;
}
if($is_check){
$msg = "입력한 값에 안전하지 않는 문자가 포함되어 있습니다. 설치를 중단합니다.";
if($is_json){
die(install_json_msg($msg));
}
die($msg);
}
return array_map_deep('stripslashes', $str);
}
}
if( ! function_exists('install_json_msg') ){
function install_json_msg($msg, $type='error'){
$error_msg = ($type==='error') ? $msg : '';
$success_msg = ($type==='success') ? $msg : '';
$exists_msg = ($type==='exists') ? $msg : '';
return json_encode(array('error'=>$error_msg, 'success'=>$success_msg, 'exists'=>$exists_msg));
}
}
if( ! function_exists('install_error_log') ){
function install_error_log($message) {
$err_file = isset($_SERVER['SCRIPT_NAME']) ? $_SERVER['SCRIPT_NAME'] : '';
@error_log('[g5 install] '.$message.' | file: '.$err_file);
}
}
if( ! function_exists('install_html_escape') ){
function install_html_escape($str) {
return htmlspecialchars((string) $str, ENT_QUOTES, 'UTF-8');
}
}
if( ! function_exists('install_db_error') ){
function install_db_error($link=null) {
if (function_exists('mysqli_connect') && G5_MYSQLI_USE) {
if ($link) {
return mysqli_errno($link).' : '.mysqli_error($link);
}
return mysqli_connect_errno().' : '.mysqli_connect_error();
}
if (function_exists('mysql_error')) {
return $link ? mysql_errno($link).' : '.mysql_error($link) : mysql_errno().' : '.mysql_error();
}
return '';
}
}
if( ! function_exists('install_db_query') ){
function install_db_query($sql, $link) {
if (function_exists('mysqli_query') && G5_MYSQLI_USE) {
return @mysqli_query($link, $sql);
}
return @mysql_query($sql, $link);
}
}
if( ! function_exists('install_db_fetch_row') ){
function install_db_fetch_row($result) {
if (!$result) {
return false;
}
if (function_exists('mysqli_fetch_row') && G5_MYSQLI_USE) {
return mysqli_fetch_row($result);
}
return mysql_fetch_row($result);
}
}
if( ! function_exists('install_db_num_rows') ){
function install_db_num_rows($result) {
if (!$result) {
return 0;
}
if (function_exists('mysqli_num_rows') && G5_MYSQLI_USE) {
return mysqli_num_rows($result);
}
return mysql_num_rows($result);
}
}
if( ! function_exists('install_db_connect') ){
function install_db_connect($host, $user, $pass, $db) {
$result = array('link'=>false, 'error'=>'', 'message'=>'');
if (function_exists('mysqli_connect') && G5_MYSQLI_USE) {
if (function_exists('mysqli_report')) {
mysqli_report(MYSQLI_REPORT_OFF);
}
$link = @mysqli_connect($host, $user, $pass);
if (!$link) {
$result['error'] = install_db_error();
$result['message'] = 'MySQL Host, User, Password 정보를 확인해 주십시오.';
return $result;
}
if (!@mysqli_select_db($link, $db)) {
$result['link'] = $link;
$result['error'] = install_db_error($link);
$result['message'] = 'MySQL DB 정보를 확인해 주십시오.';
return $result;
}
$result['link'] = $link;
return $result;
}
if (!function_exists('mysql_connect')) {
$result['message'] = 'MySQL 확장(mysqli/mysql)이 설치되어 있지 않습니다.';
return $result;
}
$link = @mysql_connect($host, $user, $pass);
if (!$link) {
$result['error'] = install_db_error();
$result['message'] = 'MySQL Host, User, Password 정보를 확인해 주십시오.';
return $result;
}
if (!@mysql_select_db($db, $link)) {
$result['link'] = $link;
$result['error'] = install_db_error($link);
$result['message'] = 'MySQL DB 정보를 확인해 주십시오.';
return $result;
}
$result['link'] = $link;
return $result;
}
}
if( ! function_exists('install_sql_like_escape') ){
function install_sql_like_escape($str) {
return str_replace(array('\\', '%', '_'), array('\\\\', '\%', '\_'), $str);
}
}
if( ! function_exists('install_sql_escape') ){
function install_sql_escape($str, $link) {
if (function_exists('mysqli_real_escape_string') && G5_MYSQLI_USE) {
return mysqli_real_escape_string($link, $str);
}
return mysql_real_escape_string($str, $link);
}
}
if( ! function_exists('install_table_exists') ){
function install_table_exists($link, $table, &$error='') {
$error = '';
$table_like = install_sql_escape(install_sql_like_escape($table), $link);
$result = install_db_query("SHOW TABLES LIKE '{$table_like}'", $link);
if (!$result) {
$error = install_db_error($link);
install_error_log('table exists check failed: '.$error.' | table: '.$table);
return false;
}
return install_db_num_rows($result) > 0;
}
}
if( ! function_exists('install_get_existing_tables') ){
function install_get_existing_tables($link, $prefixes) {
$tables = array();
foreach ($prefixes as $prefix) {
if (!$prefix) {
continue;
}
$table_like = install_sql_escape(install_sql_like_escape($prefix).'%', $link);
$result = install_db_query("SHOW TABLES LIKE '{$table_like}'", $link);
while ($row = install_db_fetch_row($result)) {
if (isset($row[0])) {
$tables[$row[0]] = $row[0];
}
}
}
ksort($tables);
return array_values($tables);
}
}
if( ! function_exists('install_fail_page') ){
function install_fail_page($message, $link=null, $prefixes=array()) {
global $install_progress_started;
install_error_log($message);
if (!empty($install_progress_started)) {
$install_progress_started = false;
?>
</ol>
</div>
<?php
}
?>
<div class="ins_inner">
<h2>설치를 계속할 수 없습니다.</h2>
<p><?php echo nl2br(install_html_escape($message)); ?></p>
<?php
if ($link && $prefixes) {
$tables = install_get_existing_tables($link, $prefixes);
if ($tables) {
?>
<p>설치가 중간에 멈춘 경우 아래 테이블이 일부 생성되었을 수 있습니다. 다시 설치하려면 DB에서 해당 테이블을 정리하거나, 재설치 옵션을 선택한 뒤 진행해 주십시오.</p>
<ul>
<?php
for ($i=0; $i<count($tables); $i++) {
?>
<li><?php echo install_html_escape($tables[$i]); ?></li>
<?php
}
?>
</ul>
<?php
}
}
?>
<div class="inner_btn"><a href="./install_config.php">뒤로가기</a></div>
</div>
<?php
include_once('./install.inc2.php');
exit;
}
}
if( ! function_exists('install_query_or_fail') ){
function install_query_or_fail($sql, $link, $message, $prefixes=array()) {
$result = install_db_query($sql, $link);
if (!$result) {
install_error_log($message.' | '.install_db_error($link).' | SQL: '.$sql);
install_fail_page($message."\n서버 오류 로그를 확인해 주십시오.", $link, $prefixes);
}
return $result;
}
}
if( ! function_exists('install_check_db_capability') ){
function install_check_db_capability($link, $table_prefix) {
$suffix = substr(md5(uniqid('', true)), 0, 12);
$table = $table_prefix.'install_check_'.$suffix;
$charset = preg_replace('/[^0-9a-z_]/i', '', G5_DB_CHARSET);
$engine = '';
if (!$charset) {
$charset = 'utf8';
}
if (in_array(strtolower(G5_DB_ENGINE), array('innodb', 'myisam'))) {
$engine = ' ENGINE='.G5_DB_ENGINE;
}
$checks = array(
"CREATE TABLE `{$table}` (`id` int(11) NOT NULL){$engine} DEFAULT CHARSET={$charset}",
"INSERT INTO `{$table}` (`id`) VALUES (1)",
"ALTER TABLE `{$table}` ADD `memo` varchar(20) NOT NULL DEFAULT ''",
"DROP TABLE `{$table}`"
);
for ($i=0; $i<count($checks); $i++) {
if (!install_db_query($checks[$i], $link)) {
$error = install_db_error($link);
install_db_query("DROP TABLE IF EXISTS `{$table}`", $link);
install_error_log('DB capability check failed: '.$error.' | SQL: '.$checks[$i]);
return array(false, 'DB 계정에 테이블 생성/입력/수정/삭제 권한이 있는지, DB 문자셋('.G5_DB_CHARSET.')을 사용할 수 있는지 확인해 주십시오.');
}
}
return array(true, '');
}
}
if( ! function_exists('install_split_sql') ){
function install_split_sql($sql) {
$queries = array();
$query = '';
$quote = '';
$len = strlen($sql);
for ($i=0; $i<$len; $i++) {
$char = $sql[$i];
$next = ($i + 1 < $len) ? $sql[$i + 1] : '';
if ($quote) {
$query .= $char;
if ($quote !== '`' && $char === '\\' && $next !== '') {
$query .= $next;
$i++;
continue;
}
if ($char === $quote) {
$quote = '';
}
continue;
}
if ($char === "'" || $char === '"' || $char === '`') {
$quote = $char;
$query .= $char;
continue;
}
if ($char === '-' && $next === '-' && ($i === 0 || preg_match('/\s/', $sql[$i - 1]))) {
while ($i < $len && $sql[$i] !== "\n") {
$i++;
}
continue;
}
if ($char === '#') {
while ($i < $len && $sql[$i] !== "\n") {
$i++;
}
continue;
}
if ($char === '/' && $next === '*') {
$i += 2;
while ($i < $len - 1 && !($sql[$i] === '*' && $sql[$i + 1] === '/')) {
$i++;
}
$i++;
continue;
}
if ($char === ';') {
$trimmed = trim($query);
if ($trimmed !== '') {
$queries[] = $trimmed;
}
$query = '';
continue;
}
$query .= $char;
}
$trimmed = trim($query);
if ($trimmed !== '') {
$queries[] = $trimmed;
}
return $queries;
}
}
if( ! function_exists('install_load_sql_file') ){
function install_load_sql_file($file, $from_prefix, $to_prefix) {
if (!is_readable($file)) {
return false;
}
$sql = file_get_contents($file);
if ($sql === false) {
return false;
}
$sql = preg_replace('/`'.preg_quote($from_prefix, '/').'([^`]+`)/', '`'.$to_prefix.'$1', $sql);
return install_split_sql($sql);
}
}
if( ! function_exists('install_ensure_dir') ){
function install_ensure_dir($dir) {
if (!is_dir($dir) && !@mkdir($dir, G5_DIR_PERMISSION)) {
return false;
}
@chmod($dir, G5_DIR_PERMISSION);
return is_dir($dir) && is_writable($dir);
}
}
if( ! function_exists('install_file_write') ){
function install_file_write($handle, $content) {
global $install_file_write_error;
if ($install_file_write_error) {
return false;
}
$result = @fwrite($handle, $content);
if ($result === false || $result < strlen($content)) {
$install_file_write_error = true;
return false;
}
return true;
}
}
// 최신 설치 SQL을 새로 생성한 경우에만 호출한다. 과거 SQL은 실행하지 않는다.
function install_record_migrations($table_prefix)
{
$files = glob(g5_migration_path() . '/*.sql');
if (!$files) return '마이그레이션 파일을 찾을 수 없습니다. 배포본의 migrations 디렉터리를 확인해 주십시오.';
sort($files, SORT_STRING);
$migrations = array();
foreach ($files as $file) {
$migration = g5_migration_read_file($file);
if (isset($migration['error'])) return $migration['error'];
$migrations[] = $migration;
}
$table = $table_prefix . 'migrations';
$error = g5_migration_validate_table($table);
if ($error !== '') return $error;
foreach ($migrations as $migration) {
if (!g5_migration_save_record($migration, 'success', '', 0, $table)) {
return $migration['id'] . ' 설치 이력을 저장하지 못했습니다: ' . sql_error_info();
}
}
return '';
}