From ab975f48b183fac31b54789f8f40a9cd5708e9c7 Mon Sep 17 00:00:00 2001 From: zero Date: Wed, 28 Mar 2007 05:28:03 +0000 Subject: [PATCH] git-svn-id: http://xe-core.googlecode.com/svn/trunk@739 201d5d3c-b55e-5fd7-737f-ddc643e51545 --- common/js/xml_handler.js | 13 +++-- modules/board/board.view.php | 11 ++--- modules/document/document.controller.php | 20 ++++++++ modules/editor/conf/module.xml | 1 + modules/editor/editor.controller.php | 45 +++++++++++++++++ modules/editor/editor.model.php | 24 ++++++++++ modules/editor/editor.view.php | 12 ++++- modules/editor/lang/ko.lang.php | 2 + modules/editor/queries/deleteSavedDoc.xml | 9 ++++ modules/editor/queries/getSavedDocument.xml | 10 ++++ modules/editor/queries/insertSavedDoc.xml | 13 +++++ modules/editor/schemas/editor_autosave.xml | 7 ++- modules/editor/tpl/css/editor.css | 11 +++++ modules/editor/tpl/editor.html | 49 +++++++++++-------- modules/editor/tpl/js/editor.js | 53 +++++++++++++++++++++ 15 files changed, 242 insertions(+), 38 deletions(-) create mode 100644 modules/editor/queries/deleteSavedDoc.xml create mode 100644 modules/editor/queries/getSavedDocument.xml create mode 100644 modules/editor/queries/insertSavedDoc.xml diff --git a/common/js/xml_handler.js b/common/js/xml_handler.js index 635684995..fe46a2a1a 100644 --- a/common/js/xml_handler.js +++ b/common/js/xml_handler.js @@ -5,6 +5,7 @@ **/ // xml handler을 이용하는 user function +var show_waiting_message = true; function exec_xml(module, act, params, callback_func, response_tags, callback_func_arg, fo_obj) { var oXml = new xml_handler(); oXml.reset(); @@ -18,10 +19,12 @@ function exec_xml(module, act, params, callback_func, response_tags, callback_fu if(typeof(response_tags)=="undefined") response_tags = new Array('error','message'); response_tags[response_tags.length] = "redirect_url"; - var waiting_obj = document.getElementById("waitingforserverresponse"); - waiting_obj.style.visibility = "visible"; - xTop(waiting_obj, xScrollTop()+20); - xLeft(waiting_obj, xScrollLeft()+20); + if(show_waiting_message) { + var waiting_obj = xGetElementById("waitingforserverresponse"); + waiting_obj.style.visibility = "visible"; + xTop(waiting_obj, xScrollTop()+20); + xLeft(waiting_obj, xScrollLeft()+20); + } oXml.request(xml_response_filter, oXml, callback_func, response_tags, callback_func_arg, fo_obj); } @@ -30,7 +33,7 @@ function xml_response_filter(oXml, callback_func, response_tags, callback_func_a var xmlDoc = oXml.getResponseXml(); if(!xmlDoc) return null; - var waiting_obj = document.getElementById("waitingforserverresponse"); + var waiting_obj = xGetElementById("waitingforserverresponse"); waiting_obj.style.visibility = "hidden"; var ret_obj = oXml.toZMsgObject(xmlDoc, response_tags); diff --git a/modules/board/board.view.php b/modules/board/board.view.php index 00dd99334..8cdbd85f2 100644 --- a/modules/board/board.view.php +++ b/modules/board/board.view.php @@ -170,16 +170,13 @@ if($document_srl) { $document = $oDocumentModel->getDocument($document_srl, $this->grant->manager); if(!$document) { - unset($document_srl); - Context::set('document_srl',''); + unset($document_srl); + Context::set('document_srl',''); } } - // 문서 번호가 없으면 새로운 값을 받아옴 - if(!$document_srl) { - $oDB = &DB::getInstance(); - $document_srl = $oDB->getNextSequence(); - } + $oDB = &DB::getInstance(); + $document_srl = $oDB->getNextSequence(); // 글을 수정하려고 할 경우 권한이 없는 경우 비밀번호 입력화면으로 if($document&&!$document->is_granted) return $this->setTemplateFile('input_password_form'); diff --git a/modules/document/document.controller.php b/modules/document/document.controller.php index e3de4f37a..67ab168d1 100644 --- a/modules/document/document.controller.php +++ b/modules/document/document.controller.php @@ -34,6 +34,12 @@ if($obj->lock_comment!='Y') $obj->lock_comment = 'N'; if($obj->allow_trackback!='Y') $obj->allow_trackback = 'N'; + // 자동저장용 필드 제거 + unset($obj->_saved_doc_srl); + unset($obj->_saved_doc_title); + unset($obj->_saved_doc_content); + unset($obj->_saved_doc_message); + // file의 Model객체 생성 $oFileModel = &getModel('file'); @@ -77,6 +83,10 @@ // 성공하였을 경우 category_srl이 있으면 카테고리 update if($obj->category_srl) $this->updateCategoryCount($obj->category_srl); + // 자동 저장 문서 삭제 + $oEditorController = &getController('editor'); + $oEditorController->deleteSavedDoc(); + // return $this->addGrant($obj->document_srl); $output->add('document_srl',$obj->document_srl); @@ -96,6 +106,12 @@ if($obj->lock_comment!='Y') $obj->lock_comment = 'N'; if($obj->allow_trackback!='Y') $obj->allow_trackback = 'N'; + // 자동저장용 필드 제거 + unset($obj->_saved_doc_srl); + unset($obj->_saved_doc_title); + unset($obj->_saved_doc_content); + unset($obj->_saved_doc_message); + // file의 Model객체 생성 $oFileModel = &getModel('file'); @@ -155,6 +171,10 @@ if($obj->category_srl) $this->updateCategoryCount($obj->category_srl); } + // 자동 저장 문서 삭제 + $oEditorController = &getController('editor'); + $oEditorController->deleteSavedDoc(); + $output->add('document_srl',$obj->document_srl); return $output; } diff --git a/modules/editor/conf/module.xml b/modules/editor/conf/module.xml index cbdb6cd61..52eff7838 100644 --- a/modules/editor/conf/module.xml +++ b/modules/editor/conf/module.xml @@ -7,6 +7,7 @@ + diff --git a/modules/editor/editor.controller.php b/modules/editor/editor.controller.php index 37a5a0703..d7ca497c8 100644 --- a/modules/editor/editor.controller.php +++ b/modules/editor/editor.controller.php @@ -13,6 +13,51 @@ function init() { } + /** + * @brief 자동 저장 + **/ + function procSaveDoc() { + + $this->deleteSavedDoc(); + + $args->document_srl = Context::get('document_srl'); + $args->content = Context::get('content'); + $args->title = Context::get('title'); + + if(Context::get('is_logged')) { + $logged_info = Context::get('logged_info'); + $args->member_srl = $logged_info->member_srl; + } else { + $args->ipaddress = $_SERVER['REMOTE_ADDR']; + } + + // 필요한 데이터가 없으면 pass + if(!$args->document_srl || (!$args->title && !$args->content)) return new Object(0,''); + + // 저장 + $oDB = &DB::getInstance(); + $output = $oDB->executeQuery('editor.insertSavedDoc', $args); + + $this->setMessage('msg_auto_saved'); + } + + /** + * @brief 자동 저장된 글을 삭제 + * 현재 접속한 사용자를 기준 + **/ + function deleteSavedDoc() { + if(Context::get('is_logged')) { + $logged_info = Context::get('logged_info'); + $args->member_srl = $logged_info->member_srl; + } else { + $args->ipaddress = $_SERVER['REMOTE_ADDR']; + } + + // 일단 이전 저장본 삭제 + $oDB = &DB::getInstance(); + $oDB->executeQuery('editor.deleteSavedDoc', $args); + } + /** * @brief 컴포넌트를 DB에 추가 **/ diff --git a/modules/editor/editor.model.php b/modules/editor/editor.model.php index 3e2662129..c4634a501 100644 --- a/modules/editor/editor.model.php +++ b/modules/editor/editor.model.php @@ -7,6 +7,30 @@ class editorModel extends editor { + /** + * @brief 자동저장되어 있는 정보를 가져옴 + **/ + function getSavedDoc() { + // 로그인 회원이면 member_srl, 아니면 ipaddress로 저장되어 있는 문서를 찾음 + if(Context::get('is_logged')) { + $logged_info = Context::get('logged_info'); + $auto_save_args->member_srl = $logged_info->member_srl; + } else { + $auto_save_args->ipaddress = $_SERVER['REMOTE_ADDR']; + } + + $oDB = &DB::getInstance(); + $output = $oDB->executeQuery('editor.getSavedDocument', $auto_save_args); + $saved_doc = $output->data; + if(!$saved_doc) return; + + // 해당 저장본 삭제 + $oEditorController = &getController('editor'); + $oEditorController->deleteSavedDoc(); + + return $saved_doc; + } + /** * @brief component의 객체 생성 **/ diff --git a/modules/editor/editor.view.php b/modules/editor/editor.view.php index 1fde00403..0e8e13d6a 100644 --- a/modules/editor/editor.view.php +++ b/modules/editor/editor.view.php @@ -62,14 +62,22 @@ /** * @brief 에디터를 return **/ - function getEditor($upload_target_srl, $allow_fileupload = false, $enableAutoSave = false) { + function getEditor($upload_target_srl, $allow_fileupload = false, $enable_autosave = false) { + $oEditorModel = &getModel('editor'); + + // 저장된 임시본이 있는지 검사 + if($enable_autosave) { + $saved_doc = $oEditorModel->getSavedDoc(); + Context::set('saved_doc', $saved_doc); + } + Context::set('enable_autosave', $enable_autosave); + // 업로드를 위한 변수 설정 Context::set('upload_target_srl', $upload_target_srl); Context::set('allow_fileupload', $allow_fileupload); // 에디터 컴포넌트를 구함 if(!Context::get('component_list')) { - $oEditorModel = &getModel('editor'); $component_list = $oEditorModel->getComponentList(); Context::set('component_list', $component_list); } diff --git a/modules/editor/lang/ko.lang.php b/modules/editor/lang/ko.lang.php index f4fd9322e..e36a3d97c 100644 --- a/modules/editor/lang/ko.lang.php +++ b/modules/editor/lang/ko.lang.php @@ -19,4 +19,6 @@ $lang->msg_component_is_inserted = '선택하신 컴포넌트는 이미 입력되어 있습니다'; $lang->msg_component_is_first_order = '선택하신 컴포넌트는 첫번째에 위치하고 있습니다'; $lang->msg_component_is_last_order = '선택하신 컴포넌트는 마지막에 위치하고 있습니다'; + $lang->msg_load_saved_doc = "자동저장된 글이 있습니다. 복구하시겠습니까?\n복구하지 않으시면 삭제됩니다"; + $lang->msg_auto_saved = "자동 저장되었습니다"; ?> diff --git a/modules/editor/queries/deleteSavedDoc.xml b/modules/editor/queries/deleteSavedDoc.xml new file mode 100644 index 000000000..2dc806d5c --- /dev/null +++ b/modules/editor/queries/deleteSavedDoc.xml @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/modules/editor/queries/getSavedDocument.xml b/modules/editor/queries/getSavedDocument.xml new file mode 100644 index 000000000..7f0a48354 --- /dev/null +++ b/modules/editor/queries/getSavedDocument.xml @@ -0,0 +1,10 @@ + + +
+ + + + + + + diff --git a/modules/editor/queries/insertSavedDoc.xml b/modules/editor/queries/insertSavedDoc.xml new file mode 100644 index 000000000..ca3d3b0e5 --- /dev/null +++ b/modules/editor/queries/insertSavedDoc.xml @@ -0,0 +1,13 @@ + + +
+ + + + + + + + + + diff --git a/modules/editor/schemas/editor_autosave.xml b/modules/editor/schemas/editor_autosave.xml index 34634b21e..3dad21b5e 100644 --- a/modules/editor/schemas/editor_autosave.xml +++ b/modules/editor/schemas/editor_autosave.xml @@ -1,8 +1,7 @@
- - - - + + + diff --git a/modules/editor/tpl/css/editor.css b/modules/editor/tpl/css/editor.css index 9633f52f6..95291a189 100644 --- a/modules/editor/tpl/css/editor.css +++ b/modules/editor/tpl/css/editor.css @@ -148,3 +148,14 @@ div.editor_drag_down_area { .about_component_icon { vertical-align:middle; } + +div.editor_autosaved_message { + padding:5px; + margin:5px 0px 5px 0px; + border:1px solid #f8be74; + font-size:9pt; + font-weight:bold; + color:#d79619; + background-color:#feffc4; + display:none; +} diff --git a/modules/editor/tpl/editor.html b/modules/editor/tpl/editor.html index e6290552b..7fe9b8a1c 100644 --- a/modules/editor/tpl/editor.html +++ b/modules/editor/tpl/editor.html @@ -8,6 +8,13 @@ editorInit("{$upload_target_srl}"); + + + + + + +
@@ -80,31 +87,33 @@
+
{$lang->msg_auto_saved}
- - + + + -
+
- - + + - -
preview
+ +
preview
- -
- -
-
- - - - -
-
+ +
+ +
+
+ + + + +
+
diff --git a/modules/editor/tpl/js/editor.js b/modules/editor/tpl/js/editor.js index 7d17c2c02..71b86c5cf 100755 --- a/modules/editor/tpl/js/editor.js +++ b/modules/editor/tpl/js/editor.js @@ -24,6 +24,7 @@ function editorInit(upload_target_srl) { // editor 시작 (upload_target_srl로 iframe객체를 얻어서 쓰기 모드로 전환) function editorStart(upload_target_srl) { + // iframe obj를 찾음 var iframe_obj = editorGetIFrame(upload_target_srl); if(!iframe_obj) return; @@ -31,6 +32,15 @@ function editorStart(upload_target_srl) { // 현 에디터를 감싸고 있는 form문을 찾아서 content object를 찾아서 내용 sync var fo_obj = iframe_obj.parentNode; while(fo_obj.nodeName != 'FORM') { fo_obj = fo_obj.parentNode; } + // saved document에 대한 체크 + if(typeof(fo_obj._saved_doc_title)!="undefined" ) { + if(fo_obj._saved_doc_title.value || fo_obj._saved_doc_content.value) { + if(confirm(fo_obj._saved_doc_message.value)) { + fo_obj.title.value = fo_obj._saved_doc_title.value; + fo_obj.content.value = fo_obj._saved_doc_content.value; + } + } + } // 구해진 form 객체를 저장 editor_form_list[upload_target_srl] = fo_obj; @@ -82,6 +92,8 @@ function editorStart(upload_target_srl) { // 에디터의 내용을 지속적으로 fo_obj.content.value에 입력 editorSyncContent(fo_obj.content, upload_target_srl); + + if(typeof(fo_obj._saved_doc_title)!="undefined" ) editorEnableAutoSave(fo_obj, upload_target_srl); } // 여러개의 편집기를 예상하여 전역 배열 변수에 form, iframe의 정보를 넣음 @@ -103,6 +115,47 @@ function _editorSync() { } xAddEventListener(window, 'load', _editorSync); +// 자동 저장 기능 +var _autoSaveObj = {fo_obj:null, upload_target_srl:0, title:'', content:''} +function editorEnableAutoSave(fo_obj, upload_target_srl) { + var title = fo_obj.title.value; + var content = fo_obj.content.value; + _autoSaveObj = {"fo_obj":fo_obj, "upload_target_srl":upload_target_srl, "title":title, "content":content}; + setTimeout(_editorAutoSave, 5000); +} + +function _editorAutoSave() { + var fo_obj = _autoSaveObj.fo_obj; + var upload_target_srl = _autoSaveObj.upload_target_srl; + + if(fo_obj && upload_target_srl) { + var title = fo_obj.title.value; + var content = editorGetContent(upload_target_srl); + if(title.trim() != _autoSaveObj.title.trim() || content.trim() != _autoSaveObj.content.trim()) { + var params = new Array(); + params["document_srl"] = upload_target_srl; + params["title"] = title; + params["content"] = content; + + _autoSaveObj.title = title; + _autoSaveObj.content = content; + + xGetElementById("editor_autosaved_message").style.display = "block"; + setTimeout(function() {xGetElementById("editor_autosaved_message").style.display = "none";}, 3000); + show_waiting_message = false; + exec_xml("editor","procSaveDoc", params, _editorAutoSaved); + show_waiting_message = true; + return; + } + } + + setTimeout(_editorAutoSave, 3000); +} + +function _editorAutoSaved(ret_obj) { + setTimeout(_editorAutoSave, 7000); +} + // 에디터의 전체 내용 return function editorGetContent(upload_target_srl) { var iframe_obj = editorGetIFrame(upload_target_srl);