diff --git a/AvocadoEdition_Light/bbs/list.php b/AvocadoEdition_Light/bbs/list.php
index 7d0a629..a942001 100644
--- a/AvocadoEdition_Light/bbs/list.php
+++ b/AvocadoEdition_Light/bbs/list.php
@@ -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;
diff --git a/AvocadoEdition_Light/common.php b/AvocadoEdition_Light/common.php
index ec26747..60fa0dd 100644
--- a/AvocadoEdition_Light/common.php
+++ b/AvocadoEdition_Light/common.php
@@ -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!!!');
diff --git a/AvocadoEdition_Light/config.php b/AvocadoEdition_Light/config.php
index 7c3413b..67472e6 100644
--- a/AvocadoEdition_Light/config.php
+++ b/AvocadoEdition_Light/config.php
@@ -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) {
diff --git a/AvocadoEdition_Light/lib/Cache/FileCache.class.php b/AvocadoEdition_Light/lib/Cache/FileCache.class.php
new file mode 100644
index 0000000..a8f924e
--- /dev/null
+++ b/AvocadoEdition_Light/lib/Cache/FileCache.class.php
@@ -0,0 +1,198 @@
+$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 = "\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));
+ }
+}
diff --git a/AvocadoEdition_Light/lib/Cache/obj.class.php b/AvocadoEdition_Light/lib/Cache/obj.class.php
new file mode 100644
index 0000000..3f920ff
--- /dev/null
+++ b/AvocadoEdition_Light/lib/Cache/obj.class.php
@@ -0,0 +1,104 @@
+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;
diff --git a/AvocadoEdition_Light/lib/cache.lib.php b/AvocadoEdition_Light/lib/cache.lib.php
new file mode 100644
index 0000000..e2d336d
--- /dev/null
+++ b/AvocadoEdition_Light/lib/cache.lib.php
@@ -0,0 +1,125 @@
+ 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;
+}
diff --git a/AvocadoEdition_Light/lib/get_data.lib.php b/AvocadoEdition_Light/lib/get_data.lib.php
index 7d3aa59..d62b790 100644
--- a/AvocadoEdition_Light/lib/get_data.lib.php
+++ b/AvocadoEdition_Light/lib/get_data.lib.php
@@ -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 .= '';
+ $str .= '';
+ $str .= '';
+ if ($is_admin) {
+ $str .= '';
+ $str .= '';
+ }
+ $str .= '';
+ $str .= '';
+
+ return run_replace('get_board_sfl_select_options', $str, $sfl);
+}
+
+function get_qa_sfl_select_options($sfl)
+{
+
+ global $is_admin;
+
+ $str = '';
+ $str .= '';
+ $str .= '';
+ $str .= '';
+ if ($is_admin)
+ $str .= '';
+
+ 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;
+}
diff --git a/AvocadoEdition_Light/lib/thumbnail.lib.php b/AvocadoEdition_Light/lib/thumbnail.lib.php
index abb4001..2455dad 100644
--- a/AvocadoEdition_Light/lib/thumbnail.lib.php
+++ b/AvocadoEdition_Light/lib/thumbnail.lib.php
@@ -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 = '' . $thumb_tag . '';
+ $attr_href = run_replace('thumb_view_image_href', G5_BBS_URL . '/view_image.php?fn=' . urlencode($imgurl), $filename, '', $width, $height, $alt);
+ $thumb_tag = '' . $thumb_tag . '';
}
$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];
}
diff --git a/AvocadoEdition_Light/lib/url.lib.php b/AvocadoEdition_Light/lib/url.lib.php
new file mode 100644
index 0000000..268e66b
--- /dev/null
+++ b/AvocadoEdition_Light/lib/url.lib.php
@@ -0,0 +1,497 @@
+ 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("/\&/", "?", $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 .= '&wr_id=' . $no;
+ }
+ if ($query_string) {
+ if (substr($query_string, 0, 1) !== '&') {
+ $url .= '&';
+ }
+
+ $url .= $query_string;
+ }
+ } else {
+ $url = G5_BBS_URL . '/' . $folder . '.php';
+ if ($no) {
+ $url .= ($folder === 'content') ? '?co_id=' . $no : '?' . $no;
+ }
+ if ($query_string) {
+ $url .= (!$no ? '?' : '&') . $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('&', '&', $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, '', '&');
+ }
+
+ if ($add_qry) {
+ $add_param .= $add_param ? '&' . $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[] = '';
+ $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[] = '';
+ $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;
+
+}