diff --git a/adm/config_form.php b/adm/config_form.php index 6bb587a95..32a6f7bfa 100644 --- a/adm/config_form.php +++ b/adm/config_form.php @@ -63,13 +63,34 @@ if(!isset($config['cf_facebook_appid'])) { } // uniqid 테이블이 없을 경우 생성 -if(!sql_query(" select uq_id from {$g4['uniqid_table']} limit 1 ", false)) { +if(!sql_query(" DESC {$g4['uniqid_table']} ", false)) { sql_query(" CREATE TABLE IF NOT EXISTS `{$g4['uniqid_table']}` ( `uq_id` bigint(20) unsigned NOT NULL, + `uq_ip` varchar(255) NOT NULL, PRIMARY KEY (`uq_id`) ) ", false); } +if(!sql_query(" SELECT uq_ip from {$g4['uniqid_table']} limit 1 ", false)) { + sql_query(" ALTER TABLE {$g4['uniqid_table']} ADD `uq_ip` VARCHAR(255) NOT NULL "); +} + + +// 임시저장 테이블이 없을 경우 생성 +if(!sql_query(" DESC {$g4['autosave_table']} ", false)) { + sql_query(" CREATE TABLE IF NOT EXISTS `{$g4['autosave_table']}` ( + `as_id` int(11) NOT NULL AUTO_INCREMENT, + `mb_id` varchar(20) NOT NULL, + `as_uid` bigint(20) unsigned NOT NULL, + `as_subject` varchar(255) NOT NULL, + `as_content` text NOT NULL, + `as_datetime` datetime NOT NULL, + PRIMARY KEY (`as_id`), + UNIQUE KEY `as_uid` (`as_uid`), + KEY `mb_id` (`mb_id`) + ) ", false); +} + $g4['title'] = '환경설정'; include_once ('./admin.head.php'); diff --git a/bbs/ajax.autosave.php b/bbs/ajax.autosave.php new file mode 100644 index 000000000..f497d0bb1 --- /dev/null +++ b/bbs/ajax.autosave.php @@ -0,0 +1,20 @@ + \ No newline at end of file diff --git a/bbs/ajax.autosavedel.php b/bbs/ajax.autosavedel.php new file mode 100644 index 000000000..30395b04d --- /dev/null +++ b/bbs/ajax.autosavedel.php @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/bbs/ajax.autosavelist.php b/bbs/ajax.autosavelist.php new file mode 100644 index 000000000..68b214e75 --- /dev/null +++ b/bbs/ajax.autosavelist.php @@ -0,0 +1,21 @@ +\n"; +echo "\n"; +for ($i=0; $row=sql_fetch_array($result); $i++) { + $subject = htmlspecialchars(utf8_strcut($row['as_subject'], 25), ENT_QUOTES); + $datetime = substr($row['as_datetime'],2,14); + echo "\n"; + echo "{$row['as_id']}\n"; + echo "{$row['as_uid']}\n"; + echo "\n"; + echo "{$datetime}\n"; + echo "\n"; +} +echo ""; +?> \ No newline at end of file diff --git a/bbs/ajax.autosaveload.php b/bbs/ajax.autosaveload.php new file mode 100644 index 000000000..2d90ab45c --- /dev/null +++ b/bbs/ajax.autosaveload.php @@ -0,0 +1,18 @@ +\n"; +echo "\n"; +echo "\n"; +echo "\n"; +echo "\n"; +?> \ No newline at end of file diff --git a/bbs/write.php b/bbs/write.php index dfc2009a4..e6ac6970c 100644 --- a/bbs/write.php +++ b/bbs/write.php @@ -380,6 +380,9 @@ if (!G4_IS_MOBILE && $board['bo_use_dhtml_editor'] && $member['mb_level'] >= $bo } $editor_html = editor_html('wr_content', $content, $is_dhtml_editor); +// 임시 저장된 글 갯수 +$autosave_count = autosave_count($member['mb_id']); + include_once(G4_PATH.'/head.sub.php'); @include_once ($board_skin_path.'/write.head.skin.php'); include_once('./board_head.php'); diff --git a/bbs/write_update.php b/bbs/write_update.php index 1de8a0532..a73b938f6 100644 --- a/bbs/write_update.php +++ b/bbs/write_update.php @@ -555,6 +555,9 @@ for ($i=(int)$row['max_bf_no']; $i>=0; $i--) // 파일의 갯수를 게시물에 업데이트 한다. $row = sql_fetch(" select count(*) as cnt from {$g4['board_file_table']} where bo_table = '{$bo_table}' and wr_id = '{$wr_id}' "); sql_query(" update {$write_table} set wr_file = '{$row['cnt']}' where wr_id = '{$wr_id}' "); + +// 자동저장된 레코드를 삭제한다. +sql_query(" delete from g4s_autosave where as_uid = '{$uid}' "); //------------------------------------------------------------------------------ // 비밀글이라면 세션에 비밀글의 아이디를 저장한다. 자신의 글은 다시 패스워드를 묻지 않기 위함 diff --git a/head.sub.php b/head.sub.php index fb27950a4..be6cb6823 100644 --- a/head.sub.php +++ b/head.sub.php @@ -75,6 +75,7 @@ if ($is_admin) { set_cookie("device_width", screen.width, 6, g4_cookie_domain); '.PHP_EOL; + echo ''.PHP_EOL; // overflow scroll 감지 } //if(!defined('G4_IS_ADMIN')) echo $config['cf_add_script']; diff --git a/install/gnuboard4s.sql b/install/gnuboard4s.sql index da7695538..ee3bf8f63 100644 --- a/install/gnuboard4s.sql +++ b/install/gnuboard4s.sql @@ -646,4 +646,23 @@ CREATE TABLE IF NOT EXISTS `g4s_syndi_log` ( PRIMARY KEY (`content_id`,`bbs_id`) ) ENGINE=MyISAM DEFAULT CHARSET=utf8; --- -------------------------------------------------------- \ No newline at end of file +-- -------------------------------------------------------- + +-- +-- Table structure for table `g4s_autosave` +-- + +DROP TABLE IF EXISTS `g4s_autosave`; +CREATE TABLE IF NOT EXISTS `g4s_autosave` ( + `as_id` int(11) NOT NULL AUTO_INCREMENT, + `mb_id` varchar(20) NOT NULL, + `as_uid` bigint(20) unsigned NOT NULL, + `as_subject` varchar(255) NOT NULL, + `as_content` text NOT NULL, + `as_datetime` datetime NOT NULL, + PRIMARY KEY (`as_id`), + UNIQUE KEY `as_uid` (`as_uid`), + KEY `mb_id` (`mb_id`) +) ENGINE=MyISAM DEFAULT CHARSET=utf8; + +-- -------------------------------------------------------- diff --git a/install/install_db.php b/install/install_db.php index 7a2e9a0b1..936042d37 100644 --- a/install/install_db.php +++ b/install/install_db.php @@ -206,6 +206,7 @@ fwrite($f, "\$g4['visit_table'] = G4_TABLE_PREFIX.'visit'; // 방문자 테이 fwrite($f, "\$g4['visit_sum_table'] = G4_TABLE_PREFIX.'visit_sum'; // 방문자 합계 테이블\n"); fwrite($f, "\$g4['uniqid_table'] = G4_TABLE_PREFIX.'uniqid'; // 유니크한 값을 만드는 테이블\n"); fwrite($f, "\$g4['syndi_log_table'] = G4_TABLE_PREFIX.'syndi_log'; // 네이버 신디케이션 컨텐츠 삭제 로그 테이블\n"); +fwrite($f, "\$g4['autosave_table'] = G4_TABLE_PREFIX.'autosave'; // 게시글 작성시 일정시간마다 글을 임시 저장하는 테이블\n"); fwrite($f, " ?>"); fclose($f); diff --git a/js/autosave.js b/js/autosave.js new file mode 100644 index 000000000..f9684db1a --- /dev/null +++ b/js/autosave.js @@ -0,0 +1,98 @@ +// 임시 저장하는 시간을 초단위로 설정한다. +var AUTOSAVE_INTERVAL = 60; // 초 + +// 글의 제목과 내용을 바뀐 부분이 있는지 비교하기 위하여 저장해 놓는 변수 +var save_wr_subject = null; +var save_wr_content = null; + +function autosave() { + $("form#fwrite").each(function() { + if (typeof(CKEDITOR.instances.wr_content)!="undefined") + this.wr_content.value = CKEDITOR.instances.wr_content.getData(); + // 변수에 저장해 놓은 값과 다를 경우에만 임시 저장함 + if (save_wr_subject != this.wr_subject.value || save_wr_content != this.wr_content.value) { + $.ajax({ + url: g4_bbs_url+"/ajax.autosave.php", + data: { + "uid" : this.uid.value, + "subject": this.wr_subject.value, + "content": this.wr_content.value + }, + type: "POST", + success: function(data){ + if (data) { + $("#autosave_count").html(data); + } + } + }); + save_wr_subject = this.wr_subject.value; + save_wr_content = this.wr_content.value; + } + }); +} + +$(function(){ + + if (g4_is_member) { + setInterval(autosave, AUTOSAVE_INTERVAL * 1000); + } + + // 임시저장된 글목록을 가져옴 + $("#btn_autosave").click(function(){ + if ($("#autosave_pop").is(":hidden")) { + $.get(g4_bbs_url+"/ajax.autosavelist.php", function(data){ + //alert(data); + //console.log( "Data: " + data); + $("#autosave_pop ul").empty(); + if ($(data).find("list").find("item").length > 0) { + $(data).find("list").find("item").each(function(i) { + var id = $(this).find("id").text(); + var uid = $(this).find("uid").text(); + var subject = $(this).find("subject").text(); + var datetime = $(this).find("datetime").text(); + $("#autosave_pop ul").append('
  • '+subject+''+datetime+'
  • '); + $.data(document.body, "autosave_id"+i, id); + $.data(document.body, "autosave_uid"+i, uid); + }); + } + }, "xml"); + $("#autosave_pop").show(); + } else { + $("#autosave_pop").hide(); + } + }); + + // 임시저장된 글 제목과 내용을 가져와서 제목과 내용 입력박스에 노출해 줌 + $(".autosave_load").live("click", function(){ + var i = $(this).parents("li").index(); + var as_id = $.data(document.body, "autosave_id"+i); + var as_uid = $.data(document.body, "autosave_uid"+i); + $("#fwrite input[name='uid']").val(as_uid); + $.get(g4_bbs_url+"/ajax.autosaveload.php", {"as_id":as_id}, function(data){ + var subject = $(data).find("item").find("subject").text(); + var content = $(data).find("item").find("content").text(); + $("#wr_subject").val(subject); + if (typeof(CKEDITOR.instances.wr_content)!="undefined") { + CKEDITOR.instances.wr_content.setData(content); + } else { + $("#fwrite #wr_content").val(content); + } + }, "xml"); + $("#autosave_pop").hide(); + }); + + $(".autosave_del").live("click", function(){ + var i = $(this).parents("li").index(); + var as_id = $.data(document.body, "autosave_id"+i); + $.get(g4_bbs_url+"/ajax.autosavedel.php", {"as_id":as_id}, function(data){ + if (data == -1) { + alert("임시 저장된글을 삭제중에 오류가 발생하였습니다."); + } else { + $("#autosave_count").html(data); + $("#autosave_pop ul > li").eq(i).remove(); + } + }); + }); + + $(".autosave_close").click(function(){ $("#autosave_pop").hide(); }); +}); diff --git a/js/modernizr.custom.70111.js b/js/modernizr.custom.70111.js new file mode 100644 index 000000000..1a81489fb --- /dev/null +++ b/js/modernizr.custom.70111.js @@ -0,0 +1,4 @@ +/* Modernizr 2.6.2 (Custom Build) | MIT & BSD + * Build: http://modernizr.com/download/#-cssclasses-testallprops-css_overflow_scrolling + */ +;window.Modernizr=function(a,b,c){function x(a){j.cssText=a}function y(a,b){return x(prefixes.join(a+";")+(b||""))}function z(a,b){return typeof a===b}function A(a,b){return!!~(""+a).indexOf(b)}function B(a,b){for(var d in a){var e=a[d];if(!A(e,"-")&&j[e]!==c)return b=="pfx"?e:!0}return!1}function C(a,b,d){for(var e in a){var f=b[a[e]];if(f!==c)return d===!1?a[e]:z(f,"function")?f.bind(d||b):f}return!1}function D(a,b,c){var d=a.charAt(0).toUpperCase()+a.slice(1),e=(a+" "+n.join(d+" ")+d).split(" ");return z(b,"string")||z(b,"undefined")?B(e,b):(e=(a+" "+o.join(d+" ")+d).split(" "),C(e,b,c))}var d="2.6.2",e={},f=!0,g=b.documentElement,h="modernizr",i=b.createElement(h),j=i.style,k,l={}.toString,m="Webkit Moz O ms",n=m.split(" "),o=m.toLowerCase().split(" "),p={},q={},r={},s=[],t=s.slice,u,v={}.hasOwnProperty,w;!z(v,"undefined")&&!z(v.call,"undefined")?w=function(a,b){return v.call(a,b)}:w=function(a,b){return b in a&&z(a.constructor.prototype[b],"undefined")},Function.prototype.bind||(Function.prototype.bind=function(b){var c=this;if(typeof c!="function")throw new TypeError;var d=t.call(arguments,1),e=function(){if(this instanceof e){var a=function(){};a.prototype=c.prototype;var f=new a,g=c.apply(f,d.concat(t.call(arguments)));return Object(g)===g?g:f}return c.apply(b,d.concat(t.call(arguments)))};return e});for(var E in p)w(p,E)&&(u=E.toLowerCase(),e[u]=p[E](),s.push((e[u]?"":"no-")+u));return e.addTest=function(a,b){if(typeof a=="object")for(var d in a)w(a,d)&&e.addTest(d,a[d]);else{a=a.toLowerCase();if(e[a]!==c)return e;b=typeof b=="function"?b():b,typeof f!="undefined"&&f&&(g.className+=" "+(b?"":"no-")+a),e[a]=b}return e},x(""),i=k=null,e._version=d,e._domPrefixes=o,e._cssomPrefixes=n,e.testProp=function(a){return B([a])},e.testAllProps=D,g.className=g.className.replace(/(^|\s)no-js(\s|$)/,"$1$2")+(f?" js "+s.join(" "):""),e}(this,this.document),Modernizr.addTest("overflowscrolling",function(){return Modernizr.testAllProps("overflowScrolling")}); \ No newline at end of file diff --git a/lib/common.lib.php b/lib/common.lib.php index 130234136..a9885c465 100644 --- a/lib/common.lib.php +++ b/lib/common.lib.php @@ -1722,7 +1722,7 @@ function get_uniqid() // 년월일시분초에 100분의 1초 두자리를 추가함 (1/100 초 앞에 자리가 모자르면 0으로 채움) $key = date('ymdHis', time()) . str_pad((int)(microtime()*100), 2, "0", STR_PAD_LEFT); - $result = sql_query(" insert into {$g4['uniqid_table']} values ('$key') ", false); + $result = sql_query(" insert into {$g4['uniqid_table']} set uq_id = '$key', uq_ip = '{$_SERVER['REMOTE_ADDR']}' ", false); if ($result) break; // 쿼리가 정상이면 빠진다. // insert 하지 못했으면 일정시간 쉰다음 다시 유일키를 만든다. @@ -2078,4 +2078,18 @@ function googl_short_url($longUrl) return $json->id; } + + +// 임시 저장된 글 갯수 +function autosave_count($mb_id) +{ + global $g4; + + if ($mb_id) { + $row = sql_fetch(" select count(*) as cnt from {$g4['autosave_table']} where mb_id = '$mb_id' "); + return (int)$row['cnt']; + } else { + return 0; + } +} ?> \ No newline at end of file diff --git a/plugin/ckeditor/ckeditor.lib.php b/plugin/ckeditor/ckeditor.lib.php index ed4cf6013..1e7e1a12f 100644 --- a/plugin/ckeditor/ckeditor.lib.php +++ b/plugin/ckeditor/ckeditor.lib.php @@ -57,7 +57,7 @@ function get_editor_js($id, $ckeditor=true) function chk_editor_js($id, $ckeditor=true, $textarea_name="내용을") { if ( $ckeditor ) { - return "if (!{$id}_editor_data) { alert(\"$textarea_name 입력해 주십시오.\"); CKEDITOR.instances.{$id}.focus(); return false; }\n"; + return "if (!{$id}_editor_data) { alert(\"$textarea_name 입력해 주십시오.\"); CKEDITOR.instances.{$id}.focus(); return false; }\nif (typeof(f.wr_content)!=\"undefined\") f.wr_content.value = {$id}_editor_data;\n"; } else { return "if (!{$id}_editor.value) { alert(\"$textarea_name 입력해 주십시오.\"); {$id}_editor.focus(); return false; }\n"; } diff --git a/skin/board/basic/img/btn_close.gif b/skin/board/basic/img/btn_close.gif new file mode 100644 index 000000000..040b180ac Binary files /dev/null and b/skin/board/basic/img/btn_close.gif differ diff --git a/skin/board/basic/style.css b/skin/board/basic/style.css index 7047ecb95..53edf8163 100644 --- a/skin/board/basic/style.css +++ b/skin/board/basic/style.css @@ -33,6 +33,21 @@ #bo_sch {margin-bottom:10px;padding-top:5px;text-align:center} #bo_sch legend {position:absolute;margin:0;padding:0;font-size:0;line-height:0;text-indent:-9999em;overflow:hidden} +/* 게시판 쓰기 */ +#autosave_wrapper {position:relative} +#autosave_pop {display:none;z-index:10;position:absolute;top:24px;right:117px;padding:8px;width:350px;height:auto !important;height:180px;max-height:180px;border:1px solid #565656;background:#fff;overflow-y:scroll} +html.no-overflowscrolling #autosave_pop {height:auto;max-height:10000px !important} /* overflow 미지원 기기 대응 */ +#autosave_pop strong {position:absolute;font-size:0;line-height:0;overflow:hidden} +#autosave_pop div {text-align:right} +#autosave_pop button {margin:0;padding:0;border:0;background:transparent} +#autosave_pop ul {margin:10px 0;padding:0;border-top:1px solid #e9e9e9;list-style:none} +#autosave_pop li {padding:8px 5px;border-bottom:1px solid #e9e9e9;zoom:1} +#autosave_pop li:after {display:block;visibility:hidden;clear:both;content:""} +#autosave_pop a {display:block;float:left} +#autosave_pop span {display:block;float:right} +.autosave_close {cursor:pointer;} +.autosave_content {display:none;} + /* 게시판 읽기 */ #bo_v {margin-bottom:20px;padding-bottom:20px} diff --git a/skin/board/basic/write.skin.php b/skin/board/basic/write.skin.php index cec6ba51b..2122dd611 100644 --- a/skin/board/basic/write.skin.php +++ b/skin/board/basic/write.skin.php @@ -8,6 +8,7 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가
    + @@ -102,7 +103,21 @@ echo $option_hidden; - + +
    + + + + +
    + 임시 저장된 글 목록 +
    +
      +
      +
      + +
      + @@ -211,4 +226,4 @@ function fwrite_submit(f) return true; } - \ No newline at end of file + diff --git a/skin/board/gallery/write.skin.php b/skin/board/gallery/write.skin.php index cec6ba51b..cab5d12a2 100644 --- a/skin/board/gallery/write.skin.php +++ b/skin/board/gallery/write.skin.php @@ -102,7 +102,19 @@ echo $option_hidden; - + + + + + +
      + 임시 저장된 글 목록 +
      + +
      +
      + + diff --git a/skin/connect/basic/current_connect.skin.php b/skin/connect/basic/current_connect.skin.php index 4913abe9d..db1159605 100644 --- a/skin/connect/basic/current_connect.skin.php +++ b/skin/connect/basic/current_connect.skin.php @@ -16,7 +16,8 @@ if (!defined('_GNUBOARD_')) exit; // 개별 페이지 접근 불가 ".$location."";