git-svn-id: http://xe-core.googlecode.com/svn/trunk@739 201d5d3c-b55e-5fd7-737f-ddc643e51545

This commit is contained in:
zero 2007-03-28 05:28:03 +00:00
parent 32a9c0d347
commit ab975f48b1
15 changed files with 242 additions and 38 deletions

View file

@ -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);

View file

@ -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');

View file

@ -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;
}

View file

@ -7,6 +7,7 @@
<action name="dispPopup" type="view" standalone="true" />
<action name="viewComponentInfo" type="view" standalone="true" />
<action name="procSaveDoc" type="controller" standalone="true" />
<action name="procCall" type="controller" standalone="true" />
<action name="procEnableComponent" type="controller" standalone="true" />
<action name="procDisableComponent" type="controller" standalone="true" />

View file

@ -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에 추가
**/

View file

@ -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의 객체 생성
**/

View file

@ -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);
}

View file

@ -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 = "자동 저장되었습니다";
?>

View file

@ -0,0 +1,9 @@
<query id="deleteSavedDoc" action="delete">
<tables>
<table name="editor_autosave" />
</tables>
<conditions>
<condition operation="equal" column="member_srl" var="member_srl" />
<condition operation="equal" column="ipaddress" var="ipaddress" />
</conditions>
</query>

View file

@ -0,0 +1,10 @@
<query id="getSavedDocument" action="select">
<tables>
<table name="editor_autosave" />
</tables>
<columns />
<conditions>
<condition operation="equal" column="member_srl" var="member_srl" pipe="and" />
<condition operation="equal" column="ipaddress" var="ipaddress" pipe="and" />
</conditions>
</query>

View file

@ -0,0 +1,13 @@
<query id="insertSavedDoc" action="insert">
<tables>
<table name="editor_autosave" />
</tables>
<columns>
<column name="member_srl" var="member_srl" />
<column name="ipaddress" var="ipaddress" />
<column name="document_srl" var="document_srl" />
<column name="title" var="title" />
<column name="content" var="content" />
<column name="regdate" var="regdate" default="curdate()" />
</columns>
</query>

View file

@ -1,8 +1,7 @@
<table name="editor_autosave">
<column name="member_srl" type="number" size="11" notnull="notnull" default="0" primary_key="primary_key" />
<column name="ipaddress" type="varchar" size="128" notnull="notnull" index="idx_ipaddress"/>
<column name="module_srl" type="number" size="11" notnull="notnull" default="0" index="idx_srl" />
<column name="document_srl" type="number" size="11" default="0" notnull="notnull" index="idx_srl" />
<column name="member_srl" type="number" size="11" default="0" index="idx_member_srl" />
<column name="ipaddress" type="varchar" size="128" index="idx_ipaddress" />
<column name="document_srl" type="number" size="11" default="0" notnull="notnull" />
<column name="title" type="varchar" size="250" />
<column name="content" type="bigtext" notnull="notnull" />
<column name="regdate" type="date" index="idx_regdate" />

View file

@ -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;
}

View file

@ -8,6 +8,13 @@
editorInit("{$upload_target_srl}");
</script>
<!-- 자동저장용 폼 -->
<!--@if($enable_autosave)-->
<input type="hidden" name="_saved_doc_title" value="{htmlspecialchars($saved_doc->title)}" />
<input type="hidden" name="_saved_doc_content" value="{htmlspecialchars($saved_doc->content)}" />
<input type="hidden" name="_saved_doc_message" value="{$lang->msg_load_saved_doc}" />
<!--@end-->
<!-- 에디터 -->
<div class="editor_content">
@ -80,31 +87,33 @@
<!-- iframe -->
<div class="editor_iframe_box"><iframe id="editor_iframe_{$upload_target_srl}" frameBorder="0" style="border:0px;width:99%;height:300px;margin:0px;"></iframe><div class="editor_drag_down_area" id="editor_drag_bar_{$upload_target_srl}"></div></div>
<div class="editor_autosaved_message" id="editor_autosaved_message">{$lang->msg_auto_saved}</div>
</div>
<!--@if($allow_fileupload)-->
<!--%import("./js/uploader.js")-->
<script type="text/javascript">
editor_upload_init("{$upload_target_srl}");
</script>
<!-- 첨부파일 영역 -->
<!--%import("./js/uploader.js")-->
<script type="text/javascript">
editor_upload_init("{$upload_target_srl}");
</script>
<div class="editor_uploader_box">
<div class="editor_uploader_box">
<input type="hidden" name="upload_target_srl" value="{$upload_target_srl}" />
<input type="hidden" name="act" value="procUploadFile" />
<input type="hidden" name="upload_target_srl" value="{$upload_target_srl}" />
<input type="hidden" name="act" value="procUploadFile" />
<!-- 미리보기 -->
<div class="editor_preview_uploaded" id="preview_uploaded_{$upload_target_srl}"><img src="./images/blank.gif" width="100" height="100" alt="preview" /></div>
<!-- 미리보기 -->
<div class="editor_preview_uploaded" id="preview_uploaded_{$upload_target_srl}"><img src="./images/blank.gif" width="100" height="100" alt="preview" /></div>
<!-- 파일 업로드 영역 -->
<div class="editor_uploader">
<select id='uploaded_file_list_{$upload_target_srl}' size='9' class="uploaded_file_list" onclick="editor_preview(this, '{$upload_target_srl}')"></select>
</div>
<div class="editor_uploader_input_area">
<input type="button" value="{$lang->edit->upload_file}" class="editor_uploader_input" onclick="editor_remove_file('{$upload_target_srl}');return false;" />
<input type="button" value="{$lang->edit->delete_selected}" class="editor_uploader_input" onclick="editor_remove_file('{$upload_target_srl}');return false;" />
<input type="button" value="{$lang->edit->link_file}" class="editor_uploader_input" onclick="editor_insert_file('{$upload_target_srl}');return false;" />
<input type="file" size="1" name="file" id="file_uploader_{$upload_target_srl}" class="editor_uploader_file_input" onchange="editor_file_upload(this, '{$upload_target_srl}')" value="{$lang->edit->upload}" />
</div>
</div>
<!-- 파일 업로드 영역 -->
<div class="editor_uploader">
<select id='uploaded_file_list_{$upload_target_srl}' size='9' class="uploaded_file_list" onclick="editor_preview(this, '{$upload_target_srl}')"></select>
</div>
<div class="editor_uploader_input_area">
<input type="button" value="{$lang->edit->upload_file}" class="editor_uploader_input" onclick="editor_remove_file('{$upload_target_srl}');return false;" />
<input type="button" value="{$lang->edit->delete_selected}" class="editor_uploader_input" onclick="editor_remove_file('{$upload_target_srl}');return false;" />
<input type="button" value="{$lang->edit->link_file}" class="editor_uploader_input" onclick="editor_insert_file('{$upload_target_srl}');return false;" />
<input type="file" size="1" name="file" id="file_uploader_{$upload_target_srl}" class="editor_uploader_file_input" onchange="editor_file_upload(this, '{$upload_target_srl}')" value="{$lang->edit->upload}" />
</div>
</div>
<!--@end-->

View file

@ -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);