diff --git a/adm/admin.head.php b/adm/admin.head.php index 12934fc14..1ed34b228 100644 --- a/adm/admin.head.php +++ b/adm/admin.head.php @@ -1,7 +1,7 @@ 현재 DB 업그레이드가 완료된 상태입니다.'; ?> diff --git a/adm/sql_write.sql b/adm/sql_write.sql index 21cad8d7f..e4394f34a 100644 --- a/adm/sql_write.sql +++ b/adm/sql_write.sql @@ -10,6 +10,7 @@ CREATE TABLE `__TABLE_NAME__` ( `wr_option` set('html1','html2','secret','mail') NOT NULL, `wr_subject` varchar(255) NOT NULL, `wr_content` text NOT NULL, + `wr_seo_title` varchar(255) NOT NULL DEFAULT '' `wr_link1` text NOT NULL, `wr_link2` text NOT NULL, `wr_link1_hit` int(11) NOT NULL DEFAULT '0', @@ -39,6 +40,7 @@ CREATE TABLE `__TABLE_NAME__` ( `wr_9` varchar(255) NOT NULL, `wr_10` varchar(255) NOT NULL, PRIMARY KEY (`wr_id`), + KEY `wr_seo_title` (`wr_seo_title`), KEY `wr_num_reply_parent` (`wr_num`,`wr_reply`,`wr_parent`), KEY `wr_is_comment` (`wr_is_comment`,`wr_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; \ No newline at end of file diff --git a/bbs/content.php b/bbs/content.php index f9551ed80..818d52799 100644 --- a/bbs/content.php +++ b/bbs/content.php @@ -6,14 +6,18 @@ if( !isset($g5['content_table']) ){ die('관리자 모드에서 게시판관리->내용 관리를 먼저 확인해 주세요.'); } +// 내용 +if($co_seo_title){ + $co = get_content_by_field($g5['content_table'], 'content', 'co_seo_title', $co_seo_title); +} else { + $co = get_content_db($co_id); +} + if (G5_IS_MOBILE) { include_once(G5_MOBILE_PATH.'/content.php'); return; } -// 내용 -$sql = " select * from {$g5['content_table']} where co_id = '$co_id' "; -$co = sql_fetch($sql); if (!$co['co_id']) alert('등록된 내용이 없습니다.'); diff --git a/bbs/list.php b/bbs/list.php index 3ccc05a42..9677f3d32 100644 --- a/bbs/list.php +++ b/bbs/list.php @@ -200,6 +200,8 @@ if($page_rows > 0) { } } +g5_latest_cache_data($board['bo_table'], $list); + $write_pages = get_paging(G5_IS_MOBILE ? $config['cf_mobile_pages'] : $config['cf_write_pages'], $page, $total_page, get_pretty_url($bo_table, '', $qstr.'&page=')); $list_href = ''; diff --git a/bbs/view.php b/bbs/view.php index 68bfb864f..de5fd5359 100644 --- a/bbs/view.php +++ b/bbs/view.php @@ -69,14 +69,15 @@ if ($member['mb_level'] >= $board['bo_write_level']) { $reply_href = ''; if ($member['mb_level'] >= $board['bo_reply_level']) { //$reply_href = './write.php?w=r&bo_table='.$bo_table.'&wr_id='.$wr_id.$qstr; - $reply_href = get_pretty_url($bo_table, '', 'wr_id='.$wr_id.$qstr, 'write'); + $reply_href = get_pretty_url($bo_table, '', 'w=r&wr_id='.$wr_id.$qstr, 'write'); } // 수정, 삭제 링크 $update_href = $delete_href = ''; // 로그인중이고 자신의 글이라면 또는 관리자라면 비밀번호를 묻지 않고 바로 수정, 삭제 가능 if (($member['mb_id'] && ($member['mb_id'] === $write['mb_id'])) || $is_admin) { - $update_href = G5_BBS_URL.'/write.php?w=u&bo_table='.$bo_table.'&wr_id='.$wr_id.'&page='.$page.$qstr; + //$update_href = G5_BBS_URL.'/write.php?w=u&bo_table='.$bo_table.'&wr_id='.$wr_id.'&page='.$page.$qstr; + $update_href = get_pretty_url($bo_table, '', 'w=u&wr_id='.$wr_id.'&page='.$page.$qstr, 'write'); set_session('ss_delete_token', $token = uniqid(time())); $delete_href = G5_BBS_URL.'/delete.php?bo_table='.$bo_table.'&wr_id='.$wr_id.'&token='.$token.'&page='.$page.urldecode($qstr); } diff --git a/bbs/write_update.php b/bbs/write_update.php index e0d1d8ec8..b5719fd5b 100644 --- a/bbs/write_update.php +++ b/bbs/write_update.php @@ -211,7 +211,7 @@ if ($w == '' || $w == 'r') { if (!isset($_POST['wr_subject']) || !trim($_POST['wr_subject'])) alert('제목을 입력하여 주십시오.'); -$wr_seo_title = exist_seo_url_recursive('bbs', generate_seo_url($wr_subject), $write_table, $wr_id); +$wr_seo_title = exist_seo_title_recursive('bbs', generate_seo_title($wr_subject), $write_table, $wr_id); if ($w == '' || $w == 'r') { diff --git a/common.php b/common.php index b63190a25..52fbb1e9e 100644 --- a/common.php +++ b/common.php @@ -418,7 +418,7 @@ if ($bo_table) { if (isset($wr_id) && $wr_id) { $write = get_write($write_table, $wr_id); } else if (isset($wr_seo_title) && $wr_seo_title) { - $write = get_write_by_field($write_table, 'wr_seo_title', $wr_seo_title); + $write = get_content_by_field($write_table, 'bbs', 'wr_seo_title', $wr_seo_title); if( isset($write['wr_id']) ){ $wr_id = $write['wr_id']; } diff --git a/config.php b/config.php index 0079b0884..c5d57d715 100644 --- a/config.php +++ b/config.php @@ -153,6 +153,9 @@ define('G5_HANGUL', 16); // 한글 define('G5_SPACE', 32); // 공백 define('G5_SPECIAL', 64); // 특수문자 +// SEO TITLE 문단 길이 +define('G5_SEO_TITEL_WORD_CUT', 8); // SEO TITLE 문단 길이 + // 퍼미션 define('G5_DIR_PERMISSION', 0755); // 디렉토리 생성시 퍼미션 define('G5_FILE_PERMISSION', 0644); // 파일 생성시 퍼미션 diff --git a/extend/debugbar.extend.php b/extend/debugbar.extend.php index d01d8051e..a3f935665 100644 --- a/extend/debugbar.extend.php +++ b/extend/debugbar.extend.php @@ -14,7 +14,7 @@ function show_debug_bar() { } $memory_usage = function_exists( 'memory_get_peak_usage' ) ? memory_get_peak_usage() : memory_get_usage(); - $php_run_time = get_microtime()-$gml_debug['begin_time']; + $php_run_time = get_microtime()-$g5_debug['php']['begin_time']; include_once( G5_PLUGIN_PATH.'/debugbar/debugbar.php' ); } diff --git a/head.sub.php b/head.sub.php index 020900ea2..ae69e3664 100644 --- a/head.sub.php +++ b/head.sub.php @@ -8,7 +8,7 @@ if(!defined('G5_IS_ADMIN') && defined('G5_THEME_PATH') && is_file(G5_THEME_PATH. return; } -$begin_time = get_microtime(); +$g5_debug['php']['begin_time'] = $begin_time = get_microtime(); if (!isset($g5['title'])) { $g5['title'] = $config['cf_title']; diff --git a/lib/Cache/FileCache.class.php b/lib/Cache/FileCache.class.php new file mode 100644 index 000000000..f65948947 --- /dev/null +++ b/lib/Cache/FileCache.class.php @@ -0,0 +1,187 @@ +$name = $options[$name]; + } + } + } + + /** + * Fetches an entry from the cache. + * + * @param string $id + */ + public function get($id) + { + $data = $this->_get($id); + 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) + { + $cache_file_path = $this->get_cache_file_path($id); + + if ( ! is_file($cache_file_path) ) + { + return FALSE; + } + + $data = unserialize(file_get_contents( $cache_file_path )); + + if ($data['ttl'] > 0 && time() > $data['time'] + $data['ttl']) + { + 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 + ); + + if ($this->write_file($cache_file_path, serialize($contents))) + { + 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 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($data); + } +} +?> \ No newline at end of file diff --git a/lib/URI/obj.class.php b/lib/URI/obj.class.php index d77c9ebb0..194f4f923 100644 --- a/lib/URI/obj.class.php +++ b/lib/URI/obj.class.php @@ -3,21 +3,27 @@ if (!defined('_GNUBOARD_')) exit; Class G5_object_store { public $writes = array(); - + public $contents = array(); + function get($type, $key, $group ='default') { switch ($type) { case 'bbs': - if( $this->exists('bbs', $key, $group) ){ - if ( is_object($this->writes[$group][$key]) ) - return clone $this->writes[$group][$key]; - else - return $this->writes[$group][$key]; - } - return false; + $datas = $this->writes; + break; + case 'content' : + $datas = $this->contents; 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' ) { @@ -28,6 +34,9 @@ Class G5_object_store { case 'bbs': $datas = $this->writes; break; + case 'content': + $datas = $this->contents; + break; } return isset($datas[$group]) && ( isset($datas[$group][$key]) || array_key_exists($key, $datas[$group]) ); @@ -41,6 +50,9 @@ Class G5_object_store { case 'bbs': $this->writes[$group][$key] = $data; break; + case 'content': + $this->contents[$group][$key] = $data; + break; } } @@ -48,13 +60,18 @@ Class G5_object_store { function delete($key, $group='default') { switch ($type) { case 'bbs': - if ( ! $this->exists('bbs', $key, $group) ) - return false; - - unset( $this->writes[$group][$key] ); - return true; + $datas = $this->writes; + break; + case 'content': + $datas = $this->contents; break; } + + if ( ! $this->exists('bbs', $key, $group) ) + return false; + + unset( $datas[$group][$key] ); + return true; } } //end Class diff --git a/lib/cache.lib.php b/lib/cache.lib.php index ba0b43379..2cad87d3e 100644 --- a/lib/cache.lib.php +++ b/lib/cache.lib.php @@ -1,6 +1,73 @@ 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() ){ + $cache->save($key, $save_data, $ttl); + } +} + +function g5_get_cache($key){ + + if( $cache = get_cachemanage_instance() ){ + return $cache->get($key); + } + + 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(); @@ -13,4 +80,15 @@ function g5_delete_all_cache(){ } +function g5_delete_cache_by_prefix($key){ + $files = glob(G5_DATA_PATH.'/cache/'.$key.'*'); + + foreach( (array) $files as $filename){ + if(empty($filename)) continue; + + unlink($filename); + } + + return ($files) ? true : false; +} ?> \ No newline at end of file diff --git a/lib/common.lib.php b/lib/common.lib.php index c9fa12b3d..9e9c53816 100644 --- a/lib/common.lib.php +++ b/lib/common.lib.php @@ -703,33 +703,6 @@ function get_write($write_table, $wr_id, $is_cache=false) return $write; } -// 게시판 테이블에서 하나의 행을 읽음 -function get_write_by_field($write_table, $where_field='', $where_value='', $is_cache=false) -{ - global $g5, $g5_object; - - if( ! in_array($where_field, 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')) ){ - 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)."' "; - - $cache[$key] = sql_fetch($sql); - - $wr_bo_table = preg_replace('/^'.preg_quote($g5['write_prefix']).'/i', '', $write_table); - - $g5_object->set('bbs', $cache[$key]['wr_id'], $cache[$key], $wr_bo_table); - - return $cache[$key]; -} - // 게시판의 다음글 번호를 얻는다. function get_next_num($table) { @@ -2246,11 +2219,7 @@ function delete_cache_latest($bo_table) return; } - $files = glob(G5_DATA_PATH.'/cache/latest-'.$bo_table.'-*'); - if (is_array($files)) { - foreach ($files as $filename) - unlink($filename); - } + g5_delete_cache_by_prefix('latest-'.$bo_table.'-'); } // 게시판 첨부파일 썸네일 삭제 @@ -2534,6 +2503,8 @@ class html_process { } array_multisort($order, SORT_ASC, $index, SORT_ASC, $links); + + $links = apply_replace('html_process_css_files', $links); foreach($links as $link) { if(!trim($link[1])) @@ -2560,6 +2531,8 @@ class html_process { } array_multisort($order, SORT_ASC, $index, SORT_ASC, $scripts); + + $scripts = apply_replace('html_process_script_files', $scripts); foreach($scripts as $js) { if(!trim($js[1])) @@ -2588,6 +2561,17 @@ class html_process { if($javascript) $nl = "\n"; $buffer = preg_replace('#([^<]*
]*>)#', "$javascript{$nl}$1", $buffer); + + $meta_tag = apply_replace('html_process_add_meta', ''); + + if( $meta_tag ){ + /* + content + 전에 메타태그가 위치 하도록 하게 한다. + */ + $nl = "\n"; + $buffer = preg_replace('#(
';
+ }
+ }
+ }
+ g5_latest_cache_data($bo_table, $list);
+
+ if(G5_USE_CACHE) {
+
$caches = array(
'list' => $list,
'bo_subject' => sql_escape_string($bo_subject),
- );
- $cache_content = "\n\n";
- $cache_content .= base64_encode(serialize($caches)); //serialize
+ );
- fwrite($handle, $cache_content);
- fclose($handle);
-
- @chmod($cache_file, 0640);
+ g5_set_cache($cache_file_name, $caches, 3600 * $cache_time);
}
+ } else {
+ $list = $cache_list;
+ $bo_subject = (is_array($caches) && isset($caches['bo_subject'])) ? $caches['bo_subject'] : '';
}
ob_start();
diff --git a/lib/thumbnail.lib.php b/lib/thumbnail.lib.php
index 1665d207a..81f1da0fe 100644
--- a/lib/thumbnail.lib.php
+++ b/lib/thumbnail.lib.php
@@ -10,9 +10,7 @@ function get_list_thumbnail($bo_table, $wr_id, $thumb_width, $thumb_height, $is_
$filename = $alt = "";
$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);
+ $row = get_thumbnail_find_cache($bo_table, $wr_id, 'file');
if($row['bf_file']) {
$filename = $row['bf_file'];
diff --git a/lib/uri.lib.php b/lib/uri.lib.php
index 7da5ce1be..f926705fa 100644
--- a/lib/uri.lib.php
+++ b/lib/uri.lib.php
@@ -10,48 +10,65 @@ function get_pretty_url($folder, $no='', $query_string='', $action='')
global $g5, $config;
$boards = get_board_names();
+ $segments = array();
+ $url = $add_query = '';
// use shortten url
if($config['cf_bbs_rewrite']) {
- if(in_array($folder, $boards)) {
+
+ $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] = $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;
- $url = G5_URL. '/'. $folder;
if($no) {
if( $config['cf_bbs_rewrite'] > 1 ){
$get_write = get_write( $g5['write_prefix'].$folder, $no , true);
-
- if( $get_write['wr_seo_title'] ){
- $url .= '/'. urlencode($get_write['wr_seo_title']).'/';
- } else {
- $url .= '/'. $no;
- }
+
+ $segments[2] = $get_write['wr_seo_title'] ? urlencode($get_write['wr_seo_title']).'/' : urlencode($no);
} else {
- $url .= '/'. $no;
+ $segments[2] = urlencode($no);
}
} else if($action) {
- $url .= '/'. $action;
+ $segments[2] = urlencode($action);
}
} else {
- $url = G5_URL. '/'.$folder;
+ $segments[1] = $folder;
if($no) {
$no_array = explode("=", $no);
$no_value = end($no_array);
- $url .= '/'. $no_value;
+ $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) == '&') {
- $url .= preg_replace("/\&/", "?", $query_string, 1);
+ $add_query = preg_replace("/\&/", "?", $query_string, 1);
} else {
- $url .= '?'. $query_string;
+ $add_query = '?'. $query_string;
}
}
+
} else { // don't use shortten url
if(in_array($folder, $boards)) {
$url = G5_BBS_URL. '/board.php?bo_table='. $folder;
@@ -70,9 +87,11 @@ function get_pretty_url($folder, $no='', $query_string='', $action='')
$url .= ($no ? '?' : '&'). $query_string;
}
}
+
+ $segments[0] = $url;
}
- return $url;
+ return implode('/', $segments).$add_query;
}
function short_url_clean($url, $add_qry=''){
@@ -87,7 +106,7 @@ function correct_goto_url($url){
return $url.'/';
}
-function generate_seo_url($string, $wordLimit = 0){
+function generate_seo_title($string, $wordLimit=G5_SEO_TITEL_WORD_CUT){
$separator = '-';
if($wordLimit != 0){
@@ -105,6 +124,11 @@ function generate_seo_url($string, $wordLimit = 0){
);
$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);
}
@@ -118,12 +142,24 @@ 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);
+
+ echo $sql;
$exists_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 = $row['co_seo_title'];
+
} else {
return $seo_title;
}
@@ -134,7 +170,7 @@ function exist_seo_url($type, $seo_title, $write_table, $sql_id=0){
return '';
}
-function exist_seo_url_recursive($type, $seo_title, $write_table, $sql_id=0){
+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, 255 - ($count+1), '')."-$count" : $seo_title;
@@ -149,7 +185,7 @@ function exist_seo_url_recursive($type, $seo_title, $write_table, $sql_id=0){
return $seo_title_add;
}
- return exist_seo_url_recursive($type, $seo_title, $write_table, $sql_id);
+ return exist_seo_title_recursive($type, $seo_title, $write_table, $sql_id);
}
?>
\ No newline at end of file
diff --git a/mobile/content.php b/mobile/content.php
index cb683b2e1..08387f012 100644
--- a/mobile/content.php
+++ b/mobile/content.php
@@ -1,9 +1,6 @@