patch new codes

This commit is contained in:
Amberstone 2024-09-27 17:11:41 +09:00
parent e8eebf6118
commit 6b1ac80b7f
Signed by: amber
GPG key ID: 094B0E55F98D8BF1
9 changed files with 1729 additions and 91 deletions

View file

@ -112,6 +112,13 @@ if (!$sca && !$stx) {
$list[$i] = get_list($row, $board, $board_skin_url, G5_IS_MOBILE ? $board['bo_mobile_subject_len'] : $board['bo_subject_len']);
$list[$i]['is_notice'] = true;
$list[$i]['list_content'] = $list[$i]['wr_content'];
// 비밀글인 경우 리스트에서 내용이 출력되지 않게 글 내용을 지웁니다.
if (strstr($list[$i]['wr_option'], "secret")) {
$list[$i]['wr_content'] = '';
}
$i++;
$notice_count++;
@ -198,6 +205,13 @@ if ($page_rows > 0) {
$list[$i]['subject'] = search_font($stx, $list[$i]['subject']);
}
$list[$i]['is_notice'] = false;
$list[$i]['list_content'] = $list[$i]['wr_content'];
// 비밀글인 경우 리스트에서 내용이 출력되지 않게 글 내용을 지웁니다.
if (strstr($list[$i]['wr_option'], "secret")) {
$list[$i]['wr_content'] = '';
}
$list_num = $total_count - ($page - 1) * $list_page_rows - $notice_count;
$list[$i]['num'] = $list_num - $k;

View file

@ -227,11 +227,54 @@ $_REQUEST = array_map_deep(G5_ESCAPE_FUNCTION, $_REQUEST);
// 완두콩님이 알려주신 보안관련 오류 수정
// $member 에 값을 직접 넘길 수 있음
$config = [];
$member = [];
$board = [];
$group = [];
$member = [
'mb_id' => '',
'mb_level' => 1,
'mb_name' => '',
'mb_point' => 0,
'mb_certify' => '',
'mb_email' => '',
'mb_open' => '',
'mb_homepage' => '',
'mb_tel' => '',
'mb_hp' => '',
'mb_zip1' => '',
'mb_zip2' => '',
'mb_addr1' => '',
'mb_addr2' => '',
'mb_addr3' => '',
'mb_addr_jibeon' => '',
'mb_signature' => '',
'mb_profile' => ''
];
$board = [
'bo_table' => '',
'bo_skin' => '',
'bo_mobile_skin' => '',
'bo_upload_count' => 0,
'bo_use_dhtml_editor' => '',
'bo_subject' => '',
'bo_image_width' => 0
];
$group = [
'gr_device' => '',
'gr_subject' => ''
];
$article = [];
$g5 = [];
if (version_compare(phpversion(), '8.0.0', '>=')) {
$g5 = ['title' => ''];
}
$qaconfig = [];
$g5_debug = [
'php' => [],
'sql' => []
];
include_once G5_LIB_PATH . '/hook.lib.php';
include_once G5_LIB_PATH . '/get_data.lib.php';
include_once G5_LIB_PATH . '/cache.lib.php';
include_once G5_LIB_PATH . '/url.lib.php';
//==============================================================================
// 공통
@ -240,8 +283,6 @@ $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'; // 공통 라이브러리
include_once G5_LIB_PATH . '/get_data.lib.php';
$g5["font_table"] = G5_TABLE_PREFIX . "editor_fonts";
$connect_db = sql_connect(G5_MYSQL_HOST, G5_MYSQL_USER, G5_MYSQL_PASSWORD) or die('MySQL Connect Error!!!');

View file

@ -26,6 +26,10 @@ www.sir.kr 과 sir.kr 도메인은 서로 다른 도메인으로 인식합니다
define('G5_COOKIE_DOMAIN', '');
define('G5_DBCONFIG_FILE', 'dbconfig.php');
// 빈값으로 두면 DB 버전이나 호스팅사 정책의 기본값에 따라 설정됩니다.
define('G5_DB_ENGINE', '');
// utf8mb4 인코딩은 MySQL 또는 MariaDB 5.5 버전 이상을 요구합니다.
define('G5_DB_CHARSET', 'utf8');
define('G5_ADMIN_DIR', 'adm');
define('G5_BBS_DIR', 'bbs');
@ -50,6 +54,8 @@ define('G5_SYNDI_DIR', 'syndi');
define('G5_PHPMAILER_DIR', 'PHPMailer');
define('G5_SESSION_DIR', 'session');
define('G5_THEME_DIR', 'theme');
define('G5_GROUP_DIR', 'group');
define('G5_CONTENT_DIR', 'content');
// URL 은 브라우저상에서의 경로 (도메인으로 부터의)
if (G5_DOMAIN) {

View file

@ -0,0 +1,198 @@
<?php
if (!defined('_GNUBOARD_'))
exit;
class FileCache
{
/**
* The root cache directory.
* @var string
*/
protected $_cache_path = '/tmp/cache';
/** @var string */
protected $file_extension = '';
/**
* Creates a FileCache object
*
* @param array $options
*/
public function __construct($options = array())
{
$available_options = array('_cache_path', 'file_extension');
foreach ($available_options as $name) {
if (isset($options[$name])) {
$this->$name = $options[$name];
}
}
}
/**
* Fetches an entry from the cache.
*
* @param string $id
*/
public function get($id, $expired_time = 0)
{
$data = $this->_get($id, $expired_time);
return is_array($data) ? $data['data'] : FALSE;
}
protected function get_cache_file_path($id)
{
$id = str_replace(DIRECTORY_SEPARATOR, '/', $id);
$add_separator = '';
$add_file_extension = '';
if (strpos('/', $id) !== 0) {
$add_separator = '/';
}
$ext = pathinfo($id, PATHINFO_EXTENSION);
if (!(isset($ext['extension']) && $ext['extension'])) {
$add_file_extension = $this->file_extension;
}
return $this->_cache_path . $add_separator . $id . $add_file_extension;
}
protected function _get($id, $expired_time = 0)
{
$cache_file_path = $this->get_cache_file_path($id);
if (!is_file($cache_file_path)) {
return FALSE;
}
$server_time = defined('G5_SERVER_TIME') ? G5_SERVER_TIME : time();
try {
$file_contents = file_get_contents($cache_file_path);
$file_ex = explode("\n\n", $file_contents);
$data = unserialize(base64_decode($file_ex[1]));
} catch (Exception $e) {
$data = array('ttl' => 1, 'time' => $server_time - 1000);
}
if ($data['ttl'] > 0 && $server_time > $data['time'] + $data['ttl']) {
unlink($cache_file_path);
return FALSE;
}
if ($data['time'] && $expired_time && $data['time'] < ($server_time - $expired_time)) {
unlink($cache_file_path);
return FALSE;
}
return $data;
}
public function write_file($path, $data, $mode = 'wb')
{
if (!$fp = @fopen($path, $mode)) {
return FALSE;
}
flock($fp, LOCK_EX);
for ($result = $written = 0, $length = strlen($data); $written < $length; $written += $result) {
if (($result = fwrite($fp, substr($data, $written))) === FALSE) {
break;
}
}
flock($fp, LOCK_UN);
fclose($fp);
return is_int($result);
}
/**
* Deletes a cache entry.
*
* @param string $id
*
* @return bool
*/
public function delete($id)
{
$cache_file_path = $this->get_cache_file_path($id);
return file_exists($cache_file_path) ? unlink($cache_file_path) : FALSE;
}
/**
* Puts data into the cache.
*
* @param string $id
* @param mixed $data
* @param int $lifetime
*
* @return bool
*/
public function save($id, $data, $ttl = 60, $raw = FALSE)
{
$cache_file_path = $this->get_cache_file_path($id);
$contents = array(
'time' => time(),
'ttl' => $ttl,
'data' => $data
);
$cache_content = "<?php if (!defined('_GNUBOARD_')) exit; ?>\n\n";
$cache_content .= base64_encode(serialize($contents));
if ($this->write_file($cache_file_path, $cache_content)) {
chmod($cache_file_path, G5_FILE_PERMISSION);
return TRUE;
}
return FALSE;
}
/**
* Fetches a base directory to store the cache data
*
* @return string
*/
protected function getCacheDirectory()
{
return $this->_cache_path;
}
/**
* Encodes some data to a string so it can be written to disk
*
* @param mixed $data
* @param int $ttl
* @return string
*/
public function encode($data, $ttl)
{
$expire = null;
if ($ttl !== null) {
$expire = time() + $ttl;
}
return base64_encode(serialize(array($data, $expire)));
}
/**
* Decodes a string encoded by {@see encode()}
*
* Must returns a tuple (data, expire). Expire
* can be null to signal no expiration.
*
* @param string $data
* @return array (data, expire)
*/
public function decode($data)
{
return unserialize(base64_decode($data));
}
}

View file

@ -0,0 +1,104 @@
<?php
if (!defined('_GNUBOARD_'))
exit;
class G5_object_cache
{
public $writes = array();
public $contents = array();
public $etcs = array();
function get($type, $key, $group = 'default')
{
switch ($type) {
case 'bbs':
$datas = $this->writes;
break;
case 'content':
$datas = $this->contents;
break;
default:
$datas = $this->etcs;
break;
}
if ($this->exists($type, $key, $group)) {
if (is_object($datas[$group][$key]))
return clone $datas[$group][$key];
else
return $datas[$group][$key];
}
return false;
}
function exists($type, $key, $group = 'default')
{
$return_data = '';
switch ($type) {
case 'bbs':
$datas = $this->writes;
break;
case 'content':
$datas = $this->contents;
break;
default:
$datas = $this->etcs;
break;
}
return isset($datas[$group]) && (isset($datas[$group][$key]) || array_key_exists($key, $datas[$group]));
}
function set($type, $key, $data = array(), $group = 'default')
{
if (is_object($data))
$data = clone $data;
switch ($type) {
case 'bbs':
$this->writes[$group][$key] = $data;
break;
case 'content':
$this->contents[$group][$key] = $data;
break;
default:
$this->etcs[$group][$key] = $data;
break;
}
}
/**
* cache 데이터 제거
* @param string $type
* @param string $key
* @param string $group
* @return bool
*/
function delete($type, $key, $group = 'default')
{
if (!$this->exists($type, $key, $group)) {
return false;
}
switch ($type) {
case 'bbs':
$datas = &$this->writes;
break;
case 'content':
$datas = &$this->contents;
break;
default:
$datas = &$this->etcs;
break;
}
unset($datas[$group][$key]);
return true;
}
} //end Class;

View file

@ -0,0 +1,125 @@
<?php
if (!defined('_GNUBOARD_'))
exit;
include_once(dirname(__FILE__) . '/Cache/obj.class.php');
include_once(dirname(__FILE__) . '/Cache/FileCache.class.php');
function get_cachemanage_instance()
{
static $instance = null;
if (!(defined('G5_USE_CACHE') && G5_USE_CACHE))
return $instance;
$instance = run_replace('get_cachemanage_instance', $instance);
if ($instance === null) {
$options = array(
'_cache_path' => G5_DATA_PATH . '/cache',
'file_extension' => '.php',
);
$instance = new FileCache($options);
}
return $instance;
}
function g5_cache_secret_key()
{
static $str = '';
if ($str)
return $str;
$str = substr(md5($_SERVER['SERVER_SOFTWARE'] . $_SERVER['DOCUMENT_ROOT']), 0, 6);
return $str;
}
function g5_latest_cache_data($bo_table, $cache_list = array(), $find_wr_id = 0)
{
static $cache = array();
if ($bo_table && $cache_list && !isset($cache[$bo_table])) {
foreach ((array) $cache_list as $wr) {
if (empty($wr) || !isset($wr['wr_id']))
continue;
$cache[$bo_table][$wr['wr_id']] = $wr;
}
}
if ($find_wr_id && isset($cache[$bo_table][$find_wr_id])) {
return $cache[$bo_table][$find_wr_id];
}
}
function g5_set_cache($key, $save_data, $ttl = null)
{
if ($cache = get_cachemanage_instance()) {
run_event('g5_set_cache_event', $cache, $key, $save_data, $ttl);
if ((is_object($cache) && get_class($cache) === 'FileCache')) {
$cache->save($key, $save_data, $ttl);
}
}
}
function g5_get_cache($key, $expired_time = 0)
{
if ($cache = get_cachemanage_instance()) {
if ((is_object($cache) && get_class($cache) === 'FileCache')) {
return $cache->get($key, $expired_time);
}
return run_replace('g5_get_cache_replace', false, $cache, $key, $expired_time);
}
return false;
}
function g5_delete_cache($key)
{
if ($cache = get_cachemanage_instance()) {
return $cache->delete($key);
}
return false;
}
function g5_delete_all_cache()
{
$board_tables = get_board_names();
foreach ($board_tables as $board_table) {
delete_cache_latest($board_table);
}
run_event('adm_cache_delete', $board_tables);
}
function g5_delete_cache_by_prefix($key)
{
$cache = get_cachemanage_instance();
$files = null;
if ((is_object($cache) && get_class($cache) === 'FileCache')) {
$files = glob(G5_DATA_PATH . '/cache/' . $key . '*');
foreach ((array) $files as $filename) {
if (empty($filename))
continue;
unlink($filename);
}
}
$files = run_replace('g5_delete_cache_by_prefix', $files, $key, $cache);
return ($files) ? true : false;
}

View file

@ -14,8 +14,520 @@ function get_config($is_cache = false)
return $cache;
}
$sql = "SELECT * FROM {$g5['config_table']} ";
$sql = " select * from {$g5['config_table']} ";
$cache = run_replace('get_config', sql_fetch($sql));
return $cache;
}
function get_content_db($co_id, $is_cache = false)
{
global $g5, $g5_object;
static $cache = [];
$type = 'content';
$co_id = preg_replace('/[^a-z0-9_]/i', '', $co_id);
$co = $g5_object->get($type, $co_id, $type);
if (!$co) {
$cache_file_name = "{$type}-{$co_id}-" . g5_cache_secret_key();
$co = g5_get_cache($cache_file_name, 10800);
if ($co === false) {
$sql = " select * from {$g5['content_table']} where co_id = '$co_id' ";
$co = sql_fetch($sql);
g5_set_cache($cache_file_name, $co, 10800);
}
$g5_object->set($type, $co_id, $co, $type);
}
return $co;
}
function get_board_names()
{
global $g5;
static $boards = [];
$boards = run_replace('get_board_names_cache', $boards);
if (!$boards) {
$sql = " select bo_table from {$g5['board_table']} ";
$result = sql_query($sql);
while ($row = sql_fetch_array($result)) {
$boards[] = $row['bo_table'];
}
}
return $boards;
}
function get_board_db($bo_table, $is_cache = false)
{
global $g5;
static $cache = [];
$bo_table = preg_replace('/[^a-z0-9_]/i', '', $bo_table);
$cache = run_replace('get_board_db_cache', $cache, $bo_table, $is_cache);
$key = md5($bo_table);
if ($is_cache && isset($cache[$key])) {
return $cache[$key];
}
if (!($cache[$key] = run_replace('get_board_db', [], $bo_table))) {
$sql = " select * from {$g5['board_table']} where bo_table = '$bo_table' ";
$board = sql_fetch($sql);
$board_defaults = [
'bo_table' => '',
'bo_skin' => '',
'bo_mobile_skin' => '',
'bo_upload_count' => 0,
'bo_use_dhtml_editor' => '',
'bo_subject' => '',
'bo_image_width' => 0
];
$cache[$key] = array_merge($board_defaults, (array) $board);
}
return $cache[$key];
}
function get_menu_db($use_mobile = 0, $is_cache = false)
{
global $g5;
static $cache = [];
$cache = run_replace('get_menu_db_cache', $cache, $use_mobile, $is_cache);
$key = md5($use_mobile);
if ($is_cache && isset($cache[$key])) {
return $cache[$key];
}
$where = $use_mobile ? "me_mobile_use = '1'" : "me_use = '1'";
if (!($cache[$key] = run_replace('get_menu_db', [], $use_mobile))) {
$sql = " select *
from {$g5['menu_table']}
where $where
and length(me_code) = '2'
order by me_order, me_id ";
$result = sql_query($sql, false);
for ($i = 0; $row = sql_fetch_array($result); $i++) {
$row['ori_me_link'] = $row['me_link'];
$row['me_link'] = short_url_clean($row['me_link']);
$row['sub'] = isset($row['sub']) ? $row['sub'] : [];
$cache[$key][$i] = $row;
$sql2 = " select *
from {$g5['menu_table']}
where $where
and length(me_code) = '4'
and substring(me_code, 1, 2) = '{$row['me_code']}'
order by me_order, me_id ";
$result2 = sql_query($sql2);
for ($k = 0; $row2 = sql_fetch_array($result2); $k++) {
$row2['ori_me_link'] = $row2['me_link'];
$row2['me_link'] = short_url_clean($row2['me_link']);
$cache[$key][$i]['sub'][$k] = $row2;
}
}
}
return $cache[$key];
}
// 게시판 테이블에서 하나의 행을 읽음
function get_content_by_field($write_table, $type = 'bbs', $where_field = '', $where_value = '', $is_cache = false)
{
global $g5, $g5_object;
static $cache = [];
$order_key = 'wr_id';
if ($type === 'content') {
$check_array = ['co_id', 'co_html', 'co_subject', 'co_content', 'co_seo_title', 'co_mobile_content', 'co_skin', 'co_mobile_skin', 'co_tag_filter_use', 'co_hit', 'co_include_head', 'co_include_tail'];
$order_key = 'co_id';
} else {
$check_array = ['wr_id', 'wr_num', 'wr_reply', 'wr_parent', 'wr_is_comment', 'ca_name', 'wr_option', 'wr_subject', 'wr_content', 'wr_seo_title', 'wr_link1', 'wr_link2', 'wr_hit', 'wr_good', 'wr_nogood', 'mb_id', 'wr_name', 'wr_email', 'wr_homepage', 'wr_datetime', 'wr_ip', 'wr_1', 'wr_2', 'wr_3', 'wr_4', 'wr_5', 'wr_6', 'wr_7', 'wr_8', 'wr_9', 'wr_10'];
}
if (!in_array($where_field, $check_array)) {
return '';
}
$where_value = strip_tags($where_value);
$key = md5($write_table . '|' . $where_field . '|' . $where_value);
if ($is_cache && isset($cache[$key])) {
return $cache[$key];
}
$sql = " select * from {$write_table} where $where_field = '" . sql_real_escape_string($where_value) . "' order by $order_key desc limit 1 ";
$cache[$key] = sql_fetch($sql);
if ($type === 'content') {
$g5_object->set($type, $cache[$key]['co_id'], $cache[$key], 'content');
} else {
$wr_bo_table = preg_replace('/^' . preg_quote($g5['write_prefix']) . '/i', '', $write_table);
$g5_object->set($type, $cache[$key]['wr_id'], $cache[$key], $wr_bo_table);
}
return $cache[$key];
}
// 게시판 첨부파일 테이블에서 하나의 행을 읽음
function get_board_file_db($bo_table, $wr_id, $fields = '*', $add_where = '', $is_cache = false)
{
global $g5;
static $cache = [];
$wr_id = (int) $wr_id;
$key = md5($bo_table . '|' . $wr_id . $fields . $add_where);
if ($is_cache && isset($cache[$key])) {
return $cache[$key];
}
$sql = " select $fields from {$g5['board_file_table']}
where bo_table = '$bo_table' and wr_id = '$wr_id' $add_where order by bf_no limit 0, 1 ";
$cache[$key] = sql_fetch($sql);
return $cache[$key];
}
function get_poll_db($po_id, $is_cache = false)
{
global $g5;
static $cache = [];
$po_id = (int) $po_id;
$key = md5($po_id);
if ($is_cache && isset($cache[$key])) {
return $cache[$key];
}
$sql = " select * from {$g5['poll_table']} where po_id = '{$po_id}' ";
$cache[$key] = sql_fetch($sql);
return $cache[$key];
}
function get_point_db($po_id, $is_cache = false)
{
global $g5;
static $cache = [];
$po_id = (int) $po_id;
$key = md5($po_id);
if ($is_cache && isset($cache[$key])) {
return $cache[$key];
}
$sql = " select * from {$g5['point_table']} where po_id = '{$po_id}' ";
$cache[$key] = sql_fetch($sql);
return $cache[$key];
}
function get_mail_content_db($ma_id, $is_cache = false)
{
global $g5;
static $cache = [];
$ma_id = (int) $ma_id;
$key = md5($ma_id);
if ($is_cache && isset($cache[$key])) {
return $cache[$key];
}
$sql = " select * from {$g5['mail_table']} where ma_id = '{$ma_id}' ";
$cache[$key] = sql_fetch($sql);
return $cache[$key];
}
function get_qacontent_db($qa_id, $is_cache = false)
{
global $g5;
static $cache = [];
$qa_id = (int) $qa_id;
$key = md5($qa_id);
if ($is_cache && isset($cache[$key])) {
return $cache[$key];
}
$sql = " select * from {$g5['qa_content_table']} where qa_id = '{$qa_id}' ";
$cache[$key] = sql_fetch($sql);
return $cache[$key];
}
function get_thumbnail_find_cache($bo_table, $wr_id, $wr_key)
{
global $g5;
if ($cache_content = g5_latest_cache_data($bo_table, [], $wr_id)) {
if ($wr_key === 'content') {
return $cache_content;
} else if ($wr_key === 'file' && isset($cache_content['first_file_thumb'])) {
return $cache_content['first_file_thumb'];
}
}
if ($wr_key === 'content') {
$write_table = $g5['write_prefix'] . $bo_table;
return get_write($write_table, $wr_id);
}
return get_board_file_db($bo_table, $wr_id, 'bf_file, bf_content', "and bf_type in (1, 2, 3, 18) ", true);
}
function get_write_table_name($bo_table)
{
global $g5;
return $g5['write_prefix'] . preg_replace('/[^a-z0-9_]/i', '', $bo_table);
}
function get_db_charset($charset)
{
$add_charset = $charset;
if ('utf8mb4' === $charset) {
$add_charset .= ' COLLATE utf8mb4_unicode_ci';
}
return run_replace('get_db_charset', $add_charset, $charset);
}
function get_db_create_replace($sql_str)
{
if (in_array(strtolower(G5_DB_ENGINE), ['innodb', 'myisam'])) {
$sql_str = preg_replace('/ENGINE=MyISAM/', 'ENGINE=' . G5_DB_ENGINE, $sql_str);
} else {
$sql_str = preg_replace('/ENGINE=MyISAM/', '', $sql_str);
}
if (G5_DB_CHARSET !== 'utf8') {
$sql_str = preg_replace('/CHARSET=utf8/', 'CHARACTER SET ' . get_db_charset(G5_DB_CHARSET), $sql_str);
}
return $sql_str;
}
function get_class_encrypt()
{
static $cache;
if ($cache && is_object($cache)) {
return $cache;
}
$cache = run_replace('get_class_encrypt', new str_encrypt());
return $cache;
}
function get_string_encrypt($str)
{
$new = get_class_encrypt();
$encrypt_str = $new->encrypt($str);
return $encrypt_str;
}
function get_string_decrypt($str)
{
$new = get_class_encrypt();
$decrypt_str = $new->decrypt($str);
return $decrypt_str;
}
function get_permission_debug_show()
{
global $member;
$bool = false;
if (defined('G5_DEBUG') && G5_DEBUG) {
$bool = true;
}
return run_replace('get_permission_debug_show', $bool, $member);
}
function get_check_mod_rewrite()
{
if (function_exists('apache_get_modules') && in_array('mod_rewrite', apache_get_modules()))
$mod_rewrite = 1;
elseif (isset($_SERVER['IIS_UrlRewriteModule']))
$mod_rewrite = 1;
else
$mod_rewrite = 0;
return $mod_rewrite;
}
function get_mb_icon_name($mb_id)
{
if ($icon_name = run_replace('get_mb_icon_name', '', $mb_id)) {
return $icon_name;
}
return $mb_id;
}
// 생성되면 안되는 게시판명
function get_bo_table_banned_word()
{
$folders = [G5_CONTENT_DIR, 'rss'];
foreach (glob(G5_PATH . '/*', GLOB_ONLYDIR) as $dir) {
$folders[] = basename($dir);
}
return run_replace('get_bo_table_banned_word', $folders);
}
function get_board_sort_fields($board = [], $make_key_return = '')
{
$bo_sort_fields = run_replace('get_board_sort_fields', [
['wr_num, wr_reply', '기본'],
['wr_datetime asc', '날짜 이전것 부터'],
['wr_datetime desc', '날짜 최근것 부터'],
['wr_hit asc, wr_num, wr_reply', '조회수 낮은것 부터'],
['wr_hit desc, wr_num, wr_reply', '조회수 높은것 부터'],
['wr_last asc', '최근글 이전것 부터'],
['wr_last desc', '최근글 최근것 부터'],
['wr_comment asc, wr_num, wr_reply', '댓글수 낮은것 부터'],
['wr_comment desc, wr_num, wr_reply', '댓글수 높은것 부터'],
['wr_good asc, wr_num, wr_reply', '추천수 낮은것 부터'],
['wr_good desc, wr_num, wr_reply', '추천수 높은것 부터'],
['wr_nogood asc, wr_num, wr_reply', '비추천수 낮은것 부터'],
['wr_nogood desc, wr_num, wr_reply', '비추천수 높은것 부터'],
['wr_subject asc, wr_num, wr_reply', '제목 오름차순'],
['wr_subject desc, wr_num, wr_reply', '제목 내림차순'],
['wr_name asc, wr_num, wr_reply', '글쓴이 오름차순'],
['wr_name desc, wr_num, wr_reply', '글쓴이 내림차순'],
['ca_name asc, wr_num, wr_reply', '분류명 오름차순'],
['ca_name desc, wr_num, wr_reply', '분류명 내림차순'],
], $board, $make_key_return);
if ($make_key_return) {
$returns = [];
foreach ($bo_sort_fields as $v) {
$key = preg_replace("/[\<\>\'\"\\\'\\\"\%\=\(\)\/\^\*\s]/", "", $v[0]);
$returns[$key] = $v[0];
}
return $returns;
}
return $bo_sort_fields;
}
function get_board_sfl_select_options($sfl)
{
global $is_admin;
$str = '';
$str .= '<option value="wr_subject" ' . get_selected($sfl, 'wr_subject') . '>제목</option>';
$str .= '<option value="wr_content" ' . get_selected($sfl, 'wr_content') . '>내용</option>';
$str .= '<option value="wr_subject||wr_content" ' . get_selected($sfl, 'wr_subject||wr_content') . '>제목+내용</option>';
if ($is_admin) {
$str .= '<option value="mb_id,1" ' . get_selected($sfl, 'mb_id,1') . '>회원아이디</option>';
$str .= '<option value="mb_id,0" ' . get_selected($sfl, 'mb_id,0') . '>회원아이디(코)</option>';
}
$str .= '<option value="wr_name,1" ' . get_selected($sfl, 'wr_name,1') . '>글쓴이</option>';
$str .= '<option value="wr_name,0" ' . get_selected($sfl, 'wr_name,0') . '>글쓴이(코)</option>';
return run_replace('get_board_sfl_select_options', $str, $sfl);
}
function get_qa_sfl_select_options($sfl)
{
global $is_admin;
$str = '';
$str .= '<option value="qa_subject" ' . get_selected($sfl, 'qa_subject') . '>제목</option>';
$str .= '<option value="qa_content" ' . get_selected($sfl, 'qa_content') . '>내용</option>';
$str .= '<option value="qa_name" ' . get_selected($sfl, 'qa_name') . '>글쓴이</option>';
if ($is_admin)
$str .= '<option value="mb_id" ' . get_selected($sfl, 'mb_id') . '>회원아이디</option>';
return run_replace('get_qa_sfl_select_options', $str, $sfl);
}
// 읽지 않은 메모 갯수 반환
function get_memo_not_read($mb_id, $add_where = '')
{
global $g5;
$sql = " SELECT count(*) as cnt FROM {$g5['memo_table']} WHERE me_recv_mb_id = '$mb_id' and me_type= 'recv' and me_read_datetime like '0%' $add_where ";
$row = sql_fetch($sql, false);
return isset($row['cnt']) ? $row['cnt'] : 0;
}
function get_scrap_totals($mb_id = '')
{
global $g5;
$add_where = $mb_id ? " and mb_id = '$mb_id' " : '';
$sql = " select count(*) as cnt from {$g5['scrap_table']} where 1=1 $add_where";
$row = sql_fetch($sql, false);
return isset($row['cnt']) ? $row['cnt'] : 0;
}

View file

@ -8,52 +8,63 @@ if (!defined('_GNUBOARD_'))
function get_list_thumbnail($bo_table, $wr_id, $thumb_width, $thumb_height, $is_create = false, $is_crop = false, $crop_mode = 'center', $is_sharpen = false, $um_value = '80/0.5/3')
{
global $g5, $config;
$filename = $alt = "";
$filename = $alt = $data_path = '';
$edt = false;
$sql = " select bf_file, bf_content from {$g5['board_file_table']}
where bo_table = '$bo_table' and wr_id = '$wr_id' and bf_type between '1' and '3' order by bf_no limit 0, 1 ";
$row = sql_fetch($sql);
$empty_array = array('src' => '', 'ori' => '', 'alt' => '');
if ($row['bf_file']) {
$write = get_thumbnail_find_cache($bo_table, $wr_id, 'content');
// 비밀글이면 썸네일을 노출하지 않습니다.
if (isset($write['wr_option']) && strstr($write['wr_option'], "secret")) {
return run_replace('is_secret_list_thumbnail', $empty_array, $bo_table, $write);
}
$row = get_thumbnail_find_cache($bo_table, $wr_id, 'file');
if (isset($row['bf_file']) && $row['bf_file']) {
$filename = $row['bf_file'];
$filepath = G5_DATA_PATH . '/file/' . $bo_table;
$alt = get_text($row['bf_content']);
} else {
$write_table = $g5['write_prefix'] . $bo_table;
$sql = " select wr_content from $write_table where wr_id = '$wr_id' ";
$write = sql_fetch($sql);
$matches = get_editor_image($write['wr_content'], false);
$edt = true;
for ($i = 0; $i < count($matches[1]); $i++) {
// 이미지 path 구함
$p = parse_url($matches[1][$i]);
if (strpos($p['path'], '/' . G5_DATA_DIR . '/') != 0)
$data_path = preg_replace('/^\/.*\/' . G5_DATA_DIR . '/', '/' . G5_DATA_DIR, $p['path']);
else
$data_path = $p['path'];
if ($matches = get_editor_image($write['wr_content'], false)) {
for ($i = 0; $i < count($matches[1]); $i++) {
// 이미지 path 구함
$p = parse_url($matches[1][$i]);
if (strpos($p['path'], '/' . G5_DATA_DIR . '/') != 0)
$data_path = preg_replace('/^\/.*\/' . G5_DATA_DIR . '/', '/' . G5_DATA_DIR, $p['path']);
else
$data_path = $p['path'];
$srcfile = G5_PATH . $data_path;
$srcfile = G5_PATH . $data_path;
if (preg_match("/\.({$config['cf_image_extension']})$/i", $srcfile) && is_file($srcfile)) {
$size = @getimagesize($srcfile);
if (empty($size))
continue;
if (preg_match("/\.({$config['cf_image_extension']})$/i", $srcfile) && is_file($srcfile)) {
$size = @getimagesize($srcfile);
if (empty($size))
continue;
$filename = basename($srcfile);
$filepath = dirname($srcfile);
$filename = basename($srcfile);
$filepath = dirname($srcfile);
preg_match("/alt=[\"\']?([^\"\']*)[\"\']?/", $matches[0][$i], $malt);
$alt = get_text($malt[1]);
preg_match("/alt=[\"\']?([^\"\']*)[\"\']?/", $matches[0][$i], $malt);
$alt = isset($malt[1]) ? get_text($malt[1]) : '';
break;
}
}
break;
}
$filename = run_replace('get_editor_filename', $filename, $p);
} //end for
} //end if
}
if (!$filename)
return false;
return $empty_array;
if ($thumbnail_info = run_replace('get_list_thumbnail_info', array(), array('bo_table' => $bo_table, 'wr_id' => $wr_id, 'data_path' => $data_path, 'edt' => $edt, 'filename' => $filename, 'filepath' => $filepath, 'thumb_width' => $thumb_width, 'thumb_height' => $thumb_height, 'is_create' => $is_create, 'is_crop' => $is_crop, 'crop_mode' => $crop_mode, 'is_sharpen' => $is_sharpen, 'um_value' => $um_value))) {
return $thumbnail_info;
}
$tname = thumbnail($filename, $filepath, $filepath, $thumb_width, $thumb_height, $is_create, $is_crop, $crop_mode, $is_sharpen, $um_value);
@ -68,7 +79,7 @@ function get_list_thumbnail($bo_table, $wr_id, $thumb_width, $thumb_height, $is_
$src = G5_DATA_URL . '/file/' . $bo_table . '/' . $tname;
}
} else {
return false;
return $empty_array;
}
$thumb = array("src" => $src, "ori" => $ori, "alt" => $alt);
@ -76,6 +87,22 @@ function get_list_thumbnail($bo_table, $wr_id, $thumb_width, $thumb_height, $is_
return $thumb;
}
// 게시글보기 파일 썸네일 리턴
function get_file_thumbnail($file)
{
if (!is_array($file))
return '';
if (preg_match('/(\.jpg|\.jpeg|\.gif|\.png|\.bmp|\.webp)$/i', $file['file']) && $contents = run_replace('get_file_thumbnail_tags', '', $file)) {
return $contents;
} else if ($file['view']) {
return get_view_thumbnail($file['view']);
}
return $file['view'];
}
// 게시글보기 썸네일 생성
function get_view_thumbnail($contents, $thumb_width = 0)
{
@ -90,19 +117,23 @@ function get_view_thumbnail($contents, $thumb_width = 0)
if (empty($matches))
return $contents;
$extensions = array(1 => 'gif', 2 => 'jpg', 3 => 'png', 18 => 'webp');
for ($i = 0; $i < count($matches[1]); $i++) {
$img = $matches[1][$i];
$img_tag = isset($matches[0][$i]) ? $matches[0][$i] : '';
preg_match("/src=[\'\"]?([^>\'\"]+[^>\'\"]+)/i", $img, $m);
$src = $m[1];
$src = isset($m[1]) ? $m[1] : '';
preg_match("/style=[\"\']?([^\"\'>]+)/i", $img, $m);
$style = $m[1];
$style = isset($m[1]) ? $m[1] : '';
preg_match("/width:\s*(\d+)px/", $style, $m);
$width = $m[1];
$width = isset($m[1]) ? $m[1] : '';
preg_match("/height:\s*(\d+)px/", $style, $m);
$height = $m[1];
$height = isset($m[1]) ? $m[1] : '';
preg_match("/alt=[\"\']?([^\"\']*)[\"\']?/", $img, $m);
$alt = get_text($m[1]);
$alt = isset($m[1]) ? get_text($m[1]) : '';
// 이미지 path 구함
$p = parse_url($src);
@ -118,8 +149,12 @@ function get_view_thumbnail($contents, $thumb_width = 0)
if (empty($size))
continue;
$file_ext = $extensions[$size[2]];
if (!$file_ext)
continue;
// jpg 이면 exif 체크
if ($size[2] == 2 && function_exists('exif_read_data')) {
if ($file_ext === 'jpg' && function_exists('exif_read_data')) {
$degree = 0;
$exif = @exif_read_data($srcfile);
if (!empty($exif['Orientation'])) {
@ -144,16 +179,22 @@ function get_view_thumbnail($contents, $thumb_width = 0)
}
}
// Animated GIF 체크
$is_animated = false;
if ($file_ext === 'gif') {
$is_animated = is_animated_gif($srcfile);
if ($replace_content = run_replace('thumbnail_is_animated_gif_content', '', $contents, $srcfile, $is_animated, $img_tag, $data_path, $size)) {
$contents = $replace_content;
continue;
}
}
// 원본 width가 thumb_width보다 작다면
if ($size[0] <= $thumb_width)
continue;
// Animated GIF 체크
$is_animated = false;
if ($size[2] == 1) {
$is_animated = is_animated_gif($srcfile);
}
// 썸네일 높이
$thumb_height = round(($thumb_width * $size[1]) / $size[0]);
$filename = basename($srcfile);
@ -175,17 +216,17 @@ function get_view_thumbnail($contents, $thumb_width = 0)
}
// $img_tag에 editor 경로가 있으면 원본보기 링크 추가
$img_tag = $matches[0][$i];
if (strpos($img_tag, G5_DATA_DIR . '/' . G5_EDITOR_DIR) && preg_match("/\.({$config['cf_image_extension']})$/i", $filename)) {
$imgurl = str_replace(G5_URL, "", $src);
$thumb_tag = '<a href="' . G5_BBS_URL . '/view_image.php?fn=' . urlencode($imgurl) . '" target="_blank" class="view_image">' . $thumb_tag . '</a>';
$attr_href = run_replace('thumb_view_image_href', G5_BBS_URL . '/view_image.php?fn=' . urlencode($imgurl), $filename, '', $width, $height, $alt);
$thumb_tag = '<a href="' . $attr_href . '" target="_blank" class="view_image">' . $thumb_tag . '</a>';
}
$contents = str_replace($img_tag, $thumb_tag, $contents);
}
}
return $contents;
return run_replace('get_view_thumbnail', $contents);
}
function thumbnail($filename, $source_path, $target_path, $thumb_width, $thumb_height, $is_create, $is_crop = false, $crop_mode = 'center', $is_sharpen = false, $um_value = '80/0.5/3')
@ -200,10 +241,22 @@ function thumbnail($filename, $source_path, $target_path, $thumb_width, $thumb_h
if (!is_file($source_file)) // 원본 파일이 없다면
return;
$size = @getimagesize($source_file);
if ($size[2] < 1 || $size[2] > 3) // gif, jpg, png 에 대해서만 적용
$extensions = array(1 => 'gif', 2 => 'jpg', 3 => 'png', 18 => 'webp');
$file_ext = $extensions[$size[2]]; // 파일 확장자
if (!$file_ext)
return;
// gif, jpg, png, webp 에 대해서만 적용
// if ( !(isset($size[2]) && ($size[2] == 1 || $size[2] == 2 || $size[2] == 3 || $size[2] == 18)) )
// return;
// $extensions 배열에 없는 확장자 라면 썸네일 만들지 않음
// if (!in_array($file_ext, $extensions))
// return;
if (!is_dir($target_path)) {
@mkdir($target_path, G5_DIR_PERMISSION);
@chmod($target_path, G5_DIR_PERMISSION);
@ -214,15 +267,18 @@ function thumbnail($filename, $source_path, $target_path, $thumb_width, $thumb_h
return '';
// Animated GIF는 썸네일 생성하지 않음
if ($size[2] == 1) {
if ($file_ext === 'gif') {
if (is_animated_gif($source_file))
return basename($source_file);
} else if ($file_ext === 'webp') {
if (is_animated_webp($source_file))
return basename($source_file);
}
$ext = array(1 => 'gif', 2 => 'jpg', 3 => 'png');
$thumb_filename = preg_replace("/\.[^\.]+$/i", "", $filename); // 확장자제거
$thumb_file = "$target_path/thumb-{$thumb_filename}_{$thumb_width}x{$thumb_height}." . $ext[$size[2]];
// $thumb_file = "$target_path/thumb-{$thumb_filename}_{$thumb_width}x{$thumb_height}.".$ext[$size[2]];
$thumb_file = "$target_path/thumb-{$thumb_filename}_{$thumb_width}x{$thumb_height}." . $file_ext;
$thumb_time = @filemtime($thumb_file);
$source_time = @filemtime($source_file);
@ -237,10 +293,10 @@ function thumbnail($filename, $source_path, $target_path, $thumb_width, $thumb_h
$src = null;
$degree = 0;
if ($size[2] == 1) {
if ($file_ext === 'gif') {
$src = @imagecreatefromgif($source_file);
$src_transparency = @imagecolortransparent($src);
} else if ($size[2] == 2) {
} else if ($file_ext === 'jpg') {
$src = @imagecreatefromjpeg($source_file);
if (function_exists('exif_read_data')) {
@ -272,9 +328,12 @@ function thumbnail($filename, $source_path, $target_path, $thumb_width, $thumb_h
}
}
}
} else if ($size[2] == 3) {
} else if ($file_ext === 'png') {
$src = @imagecreatefrompng($source_file);
@imagealphablending($src, true);
} else if ($file_ext === 'webp') {
$src = @imagecreatefromwebp($source_file);
@imagealphablending($src, true);
} else {
return;
}
@ -284,12 +343,16 @@ function thumbnail($filename, $source_path, $target_path, $thumb_width, $thumb_h
$is_large = true;
// width, height 설정
if ($thumb_width) {
if (!$thumb_height) {
$thumb_height = round(($thumb_width * $size[1]) / $size[0]);
} else {
if ($size[0] < $thumb_width || $size[1] < $thumb_height)
if ($crop_mode === 'center' && ($size[0] > $thumb_width || $size[1] > $thumb_height)) {
$is_large = true;
} else if ($size[0] < $thumb_width || $size[1] < $thumb_height) {
$is_large = false;
}
}
} else {
if ($thumb_height) {
@ -332,10 +395,10 @@ function thumbnail($filename, $source_path, $target_path, $thumb_width, $thumb_h
$dst = imagecreatetruecolor($dst_w, $dst_h);
if ($size[2] == 3) {
if ($file_ext === 'png') {
imagealphablending($dst, false);
imagesavealpha($dst, true);
} else if ($size[2] == 1) {
} else if ($file_ext === 'gif') {
$palletsize = imagecolorstotal($src);
if ($src_transparency >= 0 && $src_transparency < $palletsize) {
$transparent_color = imagecolorsforindex($src, $src_transparency);
@ -348,22 +411,24 @@ function thumbnail($filename, $source_path, $target_path, $thumb_width, $thumb_h
$dst = imagecreatetruecolor($dst_w, $dst_h);
$bgcolor = imagecolorallocate($dst, 255, 255, 255); // 배경색
if ($src_w > $src_h) {
$tmp_h = round(($dst_w * $src_h) / $src_w);
$dst_y = round(($dst_h - $tmp_h) / 2);
$dst_h = $tmp_h;
} else {
$tmp_w = round(($dst_h * $src_w) / $src_h);
$dst_x = round(($dst_w - $tmp_w) / 2);
$dst_w = $tmp_w;
if (!((defined('G5_USE_THUMB_RATIO') && false === G5_USE_THUMB_RATIO) || (defined('G5_THEME_USE_THUMB_RATIO') && false === G5_THEME_USE_THUMB_RATIO))) {
if ($src_w > $src_h) {
$tmp_h = round(($dst_w * $src_h) / $src_w);
$dst_y = round(($dst_h - $tmp_h) / 2);
$dst_h = $tmp_h;
} else {
$tmp_w = round(($dst_h * $src_w) / $src_h);
$dst_x = round(($dst_w - $tmp_w) / 2);
$dst_w = $tmp_w;
}
}
if ($size[2] == 3) {
if ($file_ext === 'png') {
$bgcolor = imagecolorallocatealpha($dst, 0, 0, 0, 127);
imagefill($dst, 0, 0, $bgcolor);
imagealphablending($dst, false);
imagesavealpha($dst, true);
} else if ($size[2] == 1) {
} else if ($file_ext === 'gif') {
$palletsize = imagecolorstotal($src);
if ($src_transparency >= 0 && $src_transparency < $palletsize) {
$transparent_color = imagecolorsforindex($src, $src_transparency);
@ -381,30 +446,72 @@ function thumbnail($filename, $source_path, $target_path, $thumb_width, $thumb_h
$dst = imagecreatetruecolor($dst_w, $dst_h);
$bgcolor = imagecolorallocate($dst, 255, 255, 255); // 배경색
if ($src_w < $dst_w) {
if ($src_h >= $dst_h) {
$dst_x = round(($dst_w - $src_w) / 2);
$src_h = $dst_h;
if (((defined('G5_USE_THUMB_RATIO') && false === G5_USE_THUMB_RATIO) || (defined('G5_THEME_USE_THUMB_RATIO') && false === G5_THEME_USE_THUMB_RATIO))) {
//이미지 썸네일을 비율 유지하지 않습니다. (5.2.6 버전 이하에서 처리된 부분과 같음)
if ($src_w < $dst_w) {
if ($src_h >= $dst_h) {
$dst_x = round(($dst_w - $src_w) / 2);
$src_h = $dst_h;
if ($dst_w > $src_w) {
$dst_w = $src_w;
}
} else {
$dst_x = round(($dst_w - $src_w) / 2);
$dst_y = round(($dst_h - $src_h) / 2);
$dst_w = $src_w;
$dst_h = $src_h;
}
} else {
$dst_x = round(($dst_w - $src_w) / 2);
$dst_y = round(($dst_h - $src_h) / 2);
$dst_w = $src_w;
$dst_h = $src_h;
if ($src_h < $dst_h) {
$dst_y = round(($dst_h - $src_h) / 2);
$dst_h = $src_h;
$src_w = $dst_w;
}
}
} else {
if ($src_h < $dst_h) {
$dst_y = round(($dst_h - $src_h) / 2);
$dst_h = $src_h;
$src_w = $dst_w;
//이미지 썸네일을 비율 유지하며 썸네일 생성합니다.
if ($src_w < $dst_w) {
if ($src_h >= $dst_h) {
if ($src_h > $src_w) {
$tmp_w = round(($dst_h * $src_w) / $src_h);
$dst_x = round(($dst_w - $tmp_w) / 2);
$dst_w = $tmp_w;
} else {
$dst_x = round(($dst_w - $src_w) / 2);
$src_h = $dst_h;
if ($dst_w > $src_w) {
$dst_w = $src_w;
}
}
} else {
$dst_x = round(($dst_w - $src_w) / 2);
$dst_y = round(($dst_h - $src_h) / 2);
$dst_w = $src_w;
$dst_h = $src_h;
}
} else {
if ($src_h < $dst_h) {
if ($src_w > $dst_w) {
$tmp_h = round(($dst_w * $src_h) / $src_w);
$dst_y = round(($dst_h - $tmp_h) / 2);
$dst_h = $tmp_h;
} else {
$dst_y = round(($dst_h - $src_h) / 2);
$dst_h = $src_h;
$src_w = $dst_w;
}
}
}
}
if ($size[2] == 3) {
if ($file_ext === 'png') {
$bgcolor = imagecolorallocatealpha($dst, 0, 0, 0, 127);
imagefill($dst, 0, 0, $bgcolor);
imagealphablending($dst, false);
imagesavealpha($dst, true);
} else if ($size[2] == 1) {
} else if ($file_ext === 'gif') {
$palletsize = imagecolorstotal($src);
if ($src_transparency >= 0 && $src_transparency < $palletsize) {
$transparent_color = imagecolorsforindex($src, $src_transparency);
@ -427,22 +534,24 @@ function thumbnail($filename, $source_path, $target_path, $thumb_width, $thumb_h
UnsharpMask($dst, $val[0], $val[1], $val[2]);
}
if ($size[2] == 1) {
if ($file_ext === 'gif') {
imagegif($dst, $thumb_file);
} else if ($size[2] == 3) {
} else if ($file_ext === 'png') {
if (!defined('G5_THUMB_PNG_COMPRESS'))
$png_compress = 5;
else
$png_compress = G5_THUMB_PNG_COMPRESS;
imagepng($dst, $thumb_file, $png_compress);
} else {
} else if ($file_ext === 'jpg') {
if (!defined('G5_THUMB_JPG_QUALITY'))
$jpg_quality = 90;
else
$jpg_quality = G5_THUMB_JPG_QUALITY;
imagejpeg($dst, $thumb_file, $jpg_quality);
} else if ($file_ext === 'webp') {
imagewebp($dst, $thumb_file);
}
chmod($thumb_file, G5_FILE_PERMISSION); // 추후 삭제를 위하여 파일모드 변경
@ -510,7 +619,7 @@ function UnsharpMask($img, $amount, $radius, $threshold)
$radius = abs(round($radius)); // Only integers make sense.
if ($radius == 0) {
return $img;
imagedestroy($img);
// imagedestroy($img);
}
$w = imagesx($img);
$h = imagesy($img);
@ -634,10 +743,37 @@ function UnsharpMask($img, $amount, $radius, $threshold)
}
// 움직이는 webp 파일인지 검사한다.
// 출처) https://stackoverflow.com/questions/45190469/how-to-identify-whether-webp-image-is-static-or-animated?answertab=votes#tab-top
function is_animated_webp($filename)
{
$contents = file_get_contents($filename);
$where = strpos($contents, "ANMF");
if ($where !== false) {
// animated
$is_animated = true;
} else {
// non animated
$is_animated = false;
}
return $is_animated;
}
function is_animated_gif($filename)
{
if (!($fh = @fopen($filename, 'rb')))
static $cache = array();
$key = md5($filename);
if (isset($cache[$key])) {
return $cache[$key];
}
if (!($fh = @fopen($filename, 'rb'))) {
$cache[$key] = false;
return false;
}
$count = 0;
// 출처 : http://www.php.net/manual/en/function.imagecreatefromgif.php#104473
// an animated gif contains multiple "frames", with each frame having a
@ -654,5 +790,10 @@ function is_animated_gif($filename)
}
fclose($fh);
return $count > 1;
$cache[$key] = ($count > 1) ? true : false;
run_event('is_animated_gif_after', $filename, $cache[$key]);
return $cache[$key];
}

View file

@ -0,0 +1,497 @@
<?php
if (!defined('_GNUBOARD_'))
exit;
// 짧은 주소 형식으로 만들어서 가져온다.
function get_pretty_url($folder, $no = '', $query_string = '', $action = '')
{
global $g5, $config;
$boards = get_board_names();
$segments = array();
$url = $add_query = '';
if ($url = run_replace('get_pretty_url', $url, $folder, $no, $query_string, $action)) {
return $url;
}
// use shortten url
if ($config['cf_bbs_rewrite']) {
$segments[0] = G5_URL;
if ($folder === 'content' && $no) { // 내용관리
$segments[1] = $folder;
if ($config['cf_bbs_rewrite'] > 1) {
$get_content = get_content_db($no, true);
$segments[2] = (isset($get_content['co_seo_title']) && $get_content['co_seo_title']) ? urlencode($get_content['co_seo_title']) . '/' : urlencode($no);
} else {
$segments[2] = urlencode($no);
}
} else if (in_array($folder, $boards)) { // 게시판
$segments[1] = $folder;
if ($no) {
if ($config['cf_bbs_rewrite'] > 1) {
$get_write = get_write($g5['write_prefix'] . $folder, $no, true);
$segments[2] = (isset($get_write['wr_seo_title']) && $get_write['wr_seo_title']) ? urlencode($get_write['wr_seo_title']) . '/' : urlencode($no);
} else {
$segments[2] = urlencode($no);
}
} else if ($action) {
$segments[2] = urlencode($action);
}
} else {
$segments[1] = $folder;
if ($no) {
$no_array = explode("=", $no);
$no_value = end($no_array);
$segments[2] = urlencode($no_value);
}
}
if ($query_string) {
// If the first character of the query string is '&', replace it with '?'.
if (substr($query_string, 0, 1) == '&') {
$add_query = preg_replace("/\&amp;/", "?", $query_string, 1);
} else {
$add_query = '?' . $query_string;
}
}
} else { // don't use shortten url
if (in_array($folder, $boards)) {
$url = G5_BBS_URL . '/board.php?bo_table=' . $folder;
if ($no) {
$url .= '&amp;wr_id=' . $no;
}
if ($query_string) {
if (substr($query_string, 0, 1) !== '&') {
$url .= '&amp;';
}
$url .= $query_string;
}
} else {
$url = G5_BBS_URL . '/' . $folder . '.php';
if ($no) {
$url .= ($folder === 'content') ? '?co_id=' . $no : '?' . $no;
}
if ($query_string) {
$url .= (!$no ? '?' : '&amp;') . $query_string;
}
}
$segments[0] = $url;
}
return implode('/', $segments) . $add_query;
}
function short_url_clean($string_url, $add_qry = '')
{
global $config, $g5;
if (isset($config['cf_bbs_rewrite']) && $config['cf_bbs_rewrite']) {
$string_url = str_replace('&amp;', '&', $string_url);
$url = parse_url($string_url);
$page_name = isset($url['path']) ? basename($url['path'], ".php") : '';
$array_page_names = run_replace('url_clean_page_names', array('board', 'write', 'content'));
if (stripos(preg_replace('/^https?:/i', '', $string_url), preg_replace('/^https?:/i', '', G5_BBS_URL)) === false || !in_array($page_name, $array_page_names)) { //게시판이 아니면 리턴
return run_replace('false_short_url_clean', $string_url, $url, $page_name, $array_page_names);
}
$return_url = '';
parse_str($url['query'], $vars);
/*
// 예) Array ( [scheme] => http [host] => sir.kr [path] => /bbs/board.php [query] => wr_id=1110870&bo_table=cm_free&cpage=1 [fragment] => c_1110946 )
foreach($vars as $k => $v) { $page_name .= "/".$v; }
*/
if ($page_name === 'write') {
$vars['action'] = 'write';
$allow_param_keys = array('bo_table' => '', 'action' => '');
} else if ($page_name === 'content') {
$vars['action'] = 'content';
$allow_param_keys = array('action' => '', 'co_id' => '');
} else {
$allow_param_keys = array('bo_table' => '', 'wr_id' => '');
}
$s = array();
foreach ($allow_param_keys as $key => $v) {
if (!isset($vars[$key]) || empty($vars[$key]))
continue;
$s[$key] = $vars[$key];
}
if ($config['cf_bbs_rewrite'] > 1 && $page_name === 'board' && (isset($s['wr_id']) && $s['wr_id']) && (isset($s['bo_table']) && $s['bo_table'])) {
$get_write = get_write(get_write_table_name($s['bo_table']), $s['wr_id'], true);
if ($get_write['wr_seo_title']) {
unset($s['wr_id']);
$s['wr_seo_title'] = urlencode($get_write['wr_seo_title']) . '/';
}
}
$fragment = isset($url['fragment']) ? '#' . $url['fragment'] : '';
$host = G5_URL;
if (isset($url['host'])) {
$array_file_paths = run_replace('url_clean_page_paths', array('/' . G5_BBS_DIR . '/board.php', '/' . G5_BBS_DIR . '/write.php', '/' . G5_BBS_DIR . '/content.php'));
$str_path = isset($url['path']) ? $url['path'] : '';
$http = (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') ? 'https://' : 'http://';
$port = (isset($url['port']) && ($url['port'] !== 80 || $url['port'] !== 443)) ? ':' . $url['port'] : '';
$host = $http . $url['host'] . $port . str_replace($array_file_paths, '', $str_path);
}
$add_param = '';
if ($result = array_diff_key($vars, $allow_param_keys)) {
$add_param = '?' . http_build_query($result, '', '&amp;');
}
if ($add_qry) {
$add_param .= $add_param ? '&amp;' . $add_qry : '?' . $add_qry;
}
foreach ($s as $k => $v) {
$return_url .= '/' . $v;
}
return $host . $return_url . $add_param . $fragment;
}
return $string_url;
}
function correct_goto_url($url)
{
if (substr($url, -1) !== '/') {
return $url . '/';
}
return $url;
}
function generate_seo_title($string, $wordLimit = G5_SEO_TITLE_WORD_CUT)
{
$separator = '-';
if ($wordLimit != 0) {
$wordArr = explode(' ', $string);
$string = implode(' ', array_slice($wordArr, 0, $wordLimit));
}
$quoteSeparator = preg_quote($separator, '#');
$trans = array(
'&.+?;' => '',
'[^\w\d _-]' => '',
'\s+' => $separator,
'(' . $quoteSeparator . ')+' => $separator
);
$string = strip_tags($string);
if (function_exists('mb_convert_encoding')) {
$string = mb_convert_encoding($string, 'UTF-8', 'UTF-8');
}
foreach ($trans as $key => $val) {
$string = preg_replace('#' . $key . '#iu', $val, $string);
}
$string = strtolower($string);
return trim(trim($string, $separator));
}
function exist_seo_url($type, $seo_title, $write_table, $sql_id = 0)
{
global $g5;
$exists_title = '';
$sql_id = preg_replace('/[^a-z0-9_\-]/i', '', $sql_id);
// 영카트 상품코드의 경우 - 하이픈이 들어가야 함
if ($type === 'bbs') {
$sql = "select wr_seo_title FROM {$write_table} WHERE wr_seo_title = '" . sql_real_escape_string($seo_title) . "' AND wr_id <> '$sql_id' limit 1";
$row = sql_fetch($sql);
$exists_title = isset($row['wr_seo_title']) ? $row['wr_seo_title'] : '';
} else if ($type === 'content') {
$sql = "select co_seo_title FROM {$write_table} WHERE co_seo_title = '" . sql_real_escape_string($seo_title) . "' AND co_id <> '$sql_id' limit 1";
$row = sql_fetch($sql);
$exists_title = isset($row['co_seo_title']) ? $row['co_seo_title'] : '';
} else {
return run_replace('exist_check_seo_title', $seo_title, $type, $write_table, $sql_id);
}
if ($exists_title)
return 'is_exists';
else
return '';
}
function check_case_exist_title($data, $case = G5_BBS_DIR, $is_redirect = false)
{
global $config, $g5, $board;
if ((int) $config['cf_bbs_rewrite'] !== 2) {
return;
}
$seo_title = '';
$redirect_url = '';
if ($case == G5_BBS_DIR && isset($data['wr_seo_title'])) {
$db_table = $g5['write_prefix'] . $board['bo_table'];
if (exist_seo_url($case, $data['wr_seo_title'], $db_table, $data['wr_id'])) {
$seo_title = $data['wr_seo_title'] . '-' . $data['wr_id'];
$sql = " update `{$db_table}` set wr_seo_title = '" . sql_real_escape_string($seo_title) . "' where wr_id = '{$data['wr_id']}' ";
sql_query($sql, false);
get_write($db_table, $data['wr_id'], false);
$redirect_url = get_pretty_url($board['bo_table'], $data['wr_id']);
}
} else if ($case == G5_CONTENT_DIR && isset($data['co_seo_title'])) {
$db_table = $g5['content_table'];
if (exist_seo_url($case, $data['co_seo_title'], $db_table, $data['co_id'])) {
$seo_title = $data['co_seo_title'] . '-' . substr(get_random_token_string(4), 4);
$sql = " update `{$db_table}` set co_seo_title = '" . sql_real_escape_string($seo_title) . "' where co_id = '{$data['co_id']}' ";
sql_query($sql, false);
get_content_db($data['co_id'], false);
g5_delete_cache_by_prefix('content-' . $data['co_id'] . '-');
$redirect_url = get_pretty_url($case, $data['co_id']);
}
} else if (defined('G5_SHOP_DIR') && $case == G5_SHOP_DIR && isset($data['it_seo_title'])) {
$db_table = $g5['g5_shop_item_table'];
if (shop_exist_check_seo_title($data['it_seo_title'], $case, $db_table, $data['it_id'])) {
$seo_title = $data['it_seo_title'] . '-' . substr(get_random_token_string(4), 4);
$sql = " update `{$db_table}` set it_seo_title = '" . sql_real_escape_string($seo_title) . "' where it_id = '{$data['it_id']}' ";
sql_query($sql, false);
get_shop_item($data['it_id'], false);
$redirect_url = get_pretty_url($case, $data['it_id']);
}
}
if ($is_redirect && $seo_title && $redirect_url) {
goto_url($redirect_url);
}
}
function exist_seo_title_recursive($type, $seo_title, $write_table, $sql_id = 0)
{
static $count = 0;
$seo_title_add = ($count > 0) ? utf8_strcut($seo_title, 100000 - ($count + 1), '') . "-$count" : $seo_title;
if (!exist_seo_url($type, $seo_title_add, $write_table, $sql_id)) {
return $seo_title_add;
}
$count++;
if ($count > 99998) {
return $seo_title_add;
}
return exist_seo_title_recursive($type, $seo_title, $write_table, $sql_id);
}
function seo_title_update($db_table, $pk_id, $type = 'bbs')
{
global $g5;
$pk_id = (int) $pk_id;
if ($type === 'bbs') {
$write = get_write($db_table, $pk_id, true);
if (!(isset($write['wr_seo_title']) && $write['wr_seo_title']) && (isset($write['wr_subject']) && $write['wr_subject'])) {
$wr_seo_title = exist_seo_title_recursive('bbs', generate_seo_title($write['wr_subject']), $db_table, $pk_id);
$sql = " update `{$db_table}` set wr_seo_title = '{$wr_seo_title}' where wr_id = '{$pk_id}' ";
sql_query($sql);
}
} else if ($type === 'content') {
$co = get_content_db($pk_id, true);
if (!(isset($co['co_seo_title']) && $co['co_seo_title']) && (isset($co['co_subject']) && $co['co_subject'])) {
$co_seo_title = exist_seo_title_recursive('content', generate_seo_title($co['co_subject']), $db_table, $pk_id);
$sql = " update `{$db_table}` set co_seo_title = '{$co_seo_title}' where co_id = '{$pk_id}' ";
sql_query($sql);
}
}
}
function get_nginx_conf_rules($return_string = false)
{
$get_path_url = parse_url(G5_URL);
$base_path = isset($get_path_url['path']) ? $get_path_url['path'] . '/' : '/';
$rules = array();
$rules[] = '#### ' . G5_VERSION . ' nginx rules BEGIN #####';
if ($add_rules = run_replace('add_nginx_conf_pre_rules', '', $get_path_url, $base_path, $return_string)) {
$rules[] = $add_rules;
}
$rules[] = 'if (!-e $request_filename) {';
if ($add_rules = run_replace('add_nginx_conf_rules', '', $get_path_url, $base_path, $return_string)) {
$rules[] = $add_rules;
}
$rules[] = "rewrite ^{$base_path}content/([0-9a-zA-Z_]+)$ {$base_path}" . G5_BBS_DIR . "/content.php?co_id=$1&rewrite=1 break;";
$rules[] = "rewrite ^{$base_path}content/([^/]+)/$ {$base_path}" . G5_BBS_DIR . "/content.php?co_seo_title=$1&rewrite=1 break;";
$rules[] = "rewrite ^{$base_path}rss/([0-9a-zA-Z_]+)$ {$base_path}" . G5_BBS_DIR . "/rss.php?bo_table=$1 break;";
$rules[] = "rewrite ^{$base_path}([0-9a-zA-Z_]+)$ {$base_path}" . G5_BBS_DIR . "/board.php?bo_table=$1&rewrite=1 break;";
$rules[] = "rewrite ^{$base_path}([0-9a-zA-Z_]+)/write$ {$base_path}" . G5_BBS_DIR . "/write.php?bo_table=$1&rewrite=1 break;";
$rules[] = "rewrite ^{$base_path}([0-9a-zA-Z_]+)/([^/]+)/$ {$base_path}" . G5_BBS_DIR . "/board.php?bo_table=$1&wr_seo_title=$2&rewrite=1 break;";
$rules[] = "rewrite ^{$base_path}([0-9a-zA-Z_]+)/([0-9]+)$ {$base_path}" . G5_BBS_DIR . "/board.php?bo_table=$1&wr_id=$2&rewrite=1 break;";
$rules[] = '}';
$rules[] = '#### ' . G5_VERSION . ' nginx rules END #####';
return $return_string ? implode("\n", $rules) : $rules;
}
function get_mod_rewrite_rules($return_string = false)
{
$get_path_url = parse_url(G5_URL);
$base_path = isset($get_path_url['path']) ? $get_path_url['path'] . '/' : '/';
$rules = array();
$rules[] = '#### ' . G5_VERSION . ' rewrite BEGIN #####';
$rules[] = '<IfModule mod_rewrite.c>';
$rules[] = 'RewriteEngine On';
$rules[] = 'RewriteBase ' . $base_path;
if ($add_rules = run_replace('add_mod_rewrite_pre_rules', '', $get_path_url, $base_path, $return_string)) {
$rules[] = $add_rules;
}
$rules[] = 'RewriteCond %{REQUEST_FILENAME} -f [OR]';
$rules[] = 'RewriteCond %{REQUEST_FILENAME} -d';
$rules[] = 'RewriteRule ^ - [L]';
if ($add_rules = run_replace('add_mod_rewrite_rules', '', $get_path_url, $base_path, $return_string)) {
$rules[] = $add_rules;
}
$rules[] = 'RewriteRule ^content/([0-9a-zA-Z_]+)$ ' . G5_BBS_DIR . '/content.php?co_id=$1&rewrite=1 [QSA,L]';
$rules[] = 'RewriteRule ^content/([^/]+)/$ ' . G5_BBS_DIR . '/content.php?co_seo_title=$1&rewrite=1 [QSA,L]';
$rules[] = 'RewriteRule ^rss/([0-9a-zA-Z_]+)$ ' . G5_BBS_DIR . '/rss.php?bo_table=$1 [QSA,L]';
$rules[] = 'RewriteRule ^([0-9a-zA-Z_]+)$ ' . G5_BBS_DIR . '/board.php?bo_table=$1&rewrite=1 [QSA,L]';
$rules[] = 'RewriteRule ^([0-9a-zA-Z_]+)/([^/]+)/$ ' . G5_BBS_DIR . '/board.php?bo_table=$1&wr_seo_title=$2&rewrite=1 [QSA,L]';
$rules[] = 'RewriteRule ^([0-9a-zA-Z_]+)/write$ ' . G5_BBS_DIR . '/write.php?bo_table=$1&rewrite=1 [QSA,L]';
$rules[] = 'RewriteRule ^([0-9a-zA-Z_]+)/([0-9]+)$ ' . G5_BBS_DIR . '/board.php?bo_table=$1&wr_id=$2&rewrite=1 [QSA,L]';
$rules[] = '</IfModule>';
$rules[] = '#### ' . G5_VERSION . ' rewrite END #####';
return $return_string ? implode("\n", $rules) : $rules;
}
function check_need_rewrite_rules()
{
$is_apache = (stripos($_SERVER['SERVER_SOFTWARE'], 'apache') !== false);
if ($is_apache) {
$save_path = G5_PATH . '/.htaccess';
if (!file_exists($save_path)) {
return true;
}
$rules = get_mod_rewrite_rules();
$bof_str = $rules[0];
$eof_str = end($rules);
$code = file_get_contents($save_path);
if (strpos($code, $bof_str) === false || strpos($code, $eof_str) === false) {
return true;
}
}
return false;
}
function update_rewrite_rules()
{
$is_apache = (stripos($_SERVER['SERVER_SOFTWARE'], 'apache') !== false);
if ($is_apache) {
$save_path = G5_PATH . '/.htaccess';
if ((!file_exists($save_path) && is_writable(G5_PATH)) || is_writable($save_path)) {
$rules = get_mod_rewrite_rules();
$bof_str = $rules[0];
$eof_str = end($rules);
if (file_exists($save_path)) {
$code = file_get_contents($save_path);
if ($code && strpos($code, $bof_str) !== false && strpos($code, $eof_str) !== false) {
return true;
}
}
$fp = fopen($save_path, "ab");
flock($fp, LOCK_EX);
$rewrite_str = implode("\n", $rules);
fwrite($fp, "\n");
fwrite($fp, $rewrite_str);
fwrite($fp, "\n");
flock($fp, LOCK_UN);
fclose($fp);
return true;
}
}
return false;
}