diff --git a/addons/point/point.addon.php b/addons/point/point.addon.php index f318f5a0b..aca5b5af9 100644 --- a/addons/point/point.addon.php +++ b/addons/point/point.addon.php @@ -38,7 +38,9 @@ // 게시글 작성 if(strpos($config->insert_document_act,$this->act)!==false) { - $document_srl = Context::get('document_srl'); + if(!$this->toBool()) return; + $document_srl = $this->get('document_srl'); + $oDocumentModel = &getModel('document'); $oDocument = $oDocumentModel->getDocument($document_srl); diff --git a/classes/xml/XmlQueryParser.class.php b/classes/xml/XmlQueryParser.class.php index 8b216505e..163ddcaad 100644 --- a/classes/xml/XmlQueryParser.class.php +++ b/classes/xml/XmlQueryParser.class.php @@ -214,6 +214,7 @@ if(strpos($v->var,".")===false) { if($v->default) $default_list[$v->var] = $v->default; if($v->filter) $filter_list[] = $v; + if($v->notnull) $notnull_list[] = $v->var; if($v->default) $buff .= sprintf('array("column"=>"%s", "value"=>$args->%s?$args->%s:%s,"pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->var, $v->var, $v->default, $v->pipe, $v->operation, "\n"); else $buff .= sprintf('array("column"=>"%s", "value"=>$args->%s,"pipe"=>"%s","operation"=>"%s",),%s', $v->column, $v->var, $v->pipe, $v->operation, "\n"); } else { diff --git a/common/js/common.js b/common/js/common.js index fc512f926..2f28c7f08 100644 --- a/common/js/common.js +++ b/common/js/common.js @@ -49,6 +49,19 @@ String.prototype.setQuery = function(key, val) { } } +/** + * @brief xSleep(micro time) + **/ +function xSleep(sec) { + sec = sec / 1000; + var now = new Date(); + var sleep = new Date(); + while( sleep.getTime() - now.getTime() < sec) { + sleep = new Date(); + } +} + + /** * @brief string prototype으로 trim 함수 추가 **/ diff --git a/config/config.inc.php b/config/config.inc.php index ede780f39..78b57e36b 100644 --- a/config/config.inc.php +++ b/config/config.inc.php @@ -12,7 +12,7 @@ * 이 내용은 제로보드XE의 버전을 관리자 페이지에 표시하기 위한 용도이며 * config.inc.php의 수정이 없더라도 공식 릴리즈시에 수정되어 함께 배포되어야 함 **/ - define('__ZBXE_VERSION__', '0.1.3'); + define('__ZBXE_VERSION__', '0.1.4'); /** * @brief 디버깅 메세지 출력 diff --git a/config/func.inc.php b/config/func.inc.php index 27e04032a..33a8e1640 100644 --- a/config/func.inc.php +++ b/config/func.inc.php @@ -154,7 +154,9 @@ function executeQueryArray($query_id, $args = null) { $oDB = &DB::getInstance(); $output = $oDB->executeQuery($query_id, $args); - if(!is_array($output->data)) $output->data = array($output->data); + if(!is_array($output->data) && count($output->data) > 0){ + $output->data = array($output->data); + } return $output; } diff --git a/modules/admin/lang/zh-CN.lang.php b/modules/admin/lang/zh-CN.lang.php index 9fa87e722..2794673a4 100644 --- a/modules/admin/lang/zh-CN.lang.php +++ b/modules/admin/lang/zh-CN.lang.php @@ -9,11 +9,11 @@ $lang->env_setup = "环境设置"; - $lang->env_information = "환경 정보"; - $lang->current_version = "설치된 버전"; - $lang->current_path = "설치된 경로"; - $lang->released_version = "최신 버전"; - $lang->about_download_link = "설치된 버전보다 최신의 버전이 배포되었습니다. download링크를 클릭하시면 다운 받으실 수 있습니다."; + $lang->env_information = "环境信息"; + $lang->current_version = "安装版本"; + $lang->current_path = "安装路径"; + $lang->released_version = "最新版本"; + $lang->about_download_link = "官方网站已发布新版本。请点击download链接下载最新版本。"; $lang->item_module = "模块目录"; $lang->item_addon = "插件目录"; @@ -35,7 +35,7 @@ $lang->welcome_to_zeroboard_xe = 'zeroboard XE 管理页面'; $lang->about_admin_page = "后台管理页面未完成"; - $lang->about_lang_env = "위 설정한 언어셋을 처음 방문하는 사용자들에게 동일하게 적용하기 위해서는 원하는 언어로 변경후 아래 [저장] 버튼을 클릭하시면 됩니다"; + $lang->about_lang_env = "可以设置显示给首次访问者的同一语言环境。修改语言环境后请点击 [保存] 按钮进行保存。"; $lang->zeroboard_xe_user_links = '为用户提供的链接'; $lang->zeroboard_xe_developer_links = '为开发人员提供的链接'; diff --git a/modules/blog/blog.controller.php b/modules/blog/blog.controller.php index 5f0640962..cfbd6925a 100644 --- a/modules/blog/blog.controller.php +++ b/modules/blog/blog.controller.php @@ -105,9 +105,6 @@ // comment 모듈의 controller 객체 생성 $oCommentController = &getController('comment'); - // 줄바꾸임나 태그제거등의 작업 - $obj->content = nl2br(strip_tags($obj->content)); - /** * 존재하는 댓글인지를 확인하여 존재 하지 않는 댓글이라면 신규로 등록하기 위해서 comment_srl의 sequence값을 받는다 **/ diff --git a/modules/blog/blog.view.php b/modules/blog/blog.view.php index ee0baf920..9a4e845aa 100644 --- a/modules/blog/blog.view.php +++ b/modules/blog/blog.view.php @@ -97,7 +97,7 @@ Context::setBrowserTitle($oDocument->getTitleText()); // 댓글에디터 설정 - //if($this->grant->write_comment && $oDocument->allowComment() && !$oDocument->isLocked()) $this->setCommentEditor(0, 100); + if($this->grant->write_comment && $oDocument->allowComment() && !$oDocument->isLocked()) $comment_editor[$oDocument->document_srl] = $this->getCommentEditor($oDocument->document_srl, 0, 100); // 조회수 증가 $oDocument->updateReadedCount(); @@ -110,10 +110,8 @@ } } - Context::set('oDocument', $oDocument); - // 댓글 - //$this->setCommentEditor(0, 100); + Context::set('oDocument', $oDocument); // 만약 document_srl은 있는데 page가 없다면 글만 호출된 경우 page를 구해서 세팅해주자.. if($document_srl && !$page) { @@ -152,6 +150,16 @@ Context::set('document_list', $output->data); Context::set('page_navigation', $output->page_navigation); + // 문서 갯수만큼 comment editor 생성 + if(count($output->data)) { + foreach($output->data as $obj) { + $comment_editor[$obj->document_srl] = $this->getCommentEditor($obj->document_srl, 0, 100); + } + } + + // 에디터 세팅 + Context::set('comment_editor', $comment_editor); + // 템플릿에서 사용할 검색옵션 세팅 $count_search_option = count($this->search_option); for($i=0;$i<$count_search_option;$i++) { @@ -182,12 +190,10 @@ // 지정된 글이 없다면 (신규) 새로운 번호를 만든다 if(!$oDocument->isExists()) { - unset($document_srl); + $document_srl = getNextSequence(); Context::set('document_srl',''); } - if(!$document_srl) $document_srl = getNextSequence(); - // 글을 수정하려고 할 경우 권한이 없는 경우 비밀번호 입력화면으로 if($oDocument->isExists()&&!$oDocument->isGranted()) return $this->setTemplateFile('input_password_form'); @@ -196,6 +202,8 @@ // 에디터 모듈의 getEditor를 호출하여 세팅 $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'document_srl'; + $option->content_key_name = 'content'; $option->allow_fileupload = $this->grant->fileupload; $option->enable_autosave = true; $option->enable_default_component = true; @@ -263,7 +271,7 @@ Context::set('source_comment',$source_comment); // 댓글 에디터 세팅 - //$this->setCommentEditor(0,400); + Context::set('editor', $this->getCommentEditor($document_srl, 0, 400)); $this->setTemplateFile('comment_form'); } @@ -299,7 +307,7 @@ Context::set('comment', $comment); // 댓글 에디터 세팅 - //$this->setCommentEditor($comment_srl,400); + Context::set('editor', $this->getCommentEditor($document_srl, $comment_srl, 400)); $this->setTemplateFile('comment_form'); } @@ -368,13 +376,11 @@ * 댓글의 경우 수정하는 경우가 아니라면 고유값이 없음.\n * 따라서 고유값이 없을 경우 고유값을 가져와서 지정해 주어야 함 **/ - function setCommentEditor($comment_srl=0, $height = 100) { - return; - if(!$comment_srl) { - $comment_srl = getNextSequence(); - Context::set('comment_srl', $comment_srl); - } + function getCommentEditor($editor_sequence, $comment_srl=0, $height = 100) { $oEditorModel = &getModel('editor'); + $option->editor_sequence = $editor_sequence; + $option->primary_key_name = 'comment_srl'; + $option->content_key_name = 'content'; $option->allow_fileupload = $this->grant->comment_fileupload; $option->enable_autosave = false; $option->enable_default_component = true; @@ -382,7 +388,7 @@ $option->resizable = true; $option->height = $height; $comment_editor = $oEditorModel->getEditor($comment_srl, $option); - Context::set('comment_editor', $comment_editor); + return $comment_editor; } } diff --git a/modules/blog/skins/cozy_simple/comment_form.html b/modules/blog/skins/cozy_simple/comment_form.html index ed27feb78..f922c34bd 100644 --- a/modules/blog/skins/cozy_simple/comment_form.html +++ b/modules/blog/skins/cozy_simple/comment_form.html @@ -35,6 +35,7 @@ +
@@ -53,7 +54,7 @@
- +
{$editor?$editor:$comment_editor[$document_srl]}
diff --git a/modules/blog/skins/cozy_simple/filter/insert_comment.xml b/modules/blog/skins/cozy_simple/filter/insert_comment.xml index 1a3245e34..cedadbc8e 100644 --- a/modules/blog/skins/cozy_simple/filter/insert_comment.xml +++ b/modules/blog/skins/cozy_simple/filter/insert_comment.xml @@ -1,6 +1,5 @@
- diff --git a/modules/blog/skins/cozy_simple/js/blog.js b/modules/blog/skins/cozy_simple/js/blog.js index 1573f5106..b430fbaac 100644 --- a/modules/blog/skins/cozy_simple/js/blog.js +++ b/modules/blog/skins/cozy_simple/js/blog.js @@ -26,8 +26,8 @@ function completeDeleteDocument(ret_obj) { var mid = ret_obj['mid']; var page = ret_obj['page']; - var url = "./?mid="+mid; - if(page) url += "&page="+page; + var url = current_url.setQuery('mid',mid).setQuery('act','').setQuery('document_srl',''); + if(page) url = url.setQuery('page',page); alert(message); @@ -73,8 +73,8 @@ function completeDeleteComment(ret_obj) { var document_srl = ret_obj['document_srl']; var page = ret_obj['page']; - var url = "./?mid="+mid+'&document_srl='+document_srl; - if(page) url += "&page="+page; + var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); + if(page) url = url.setQuery('page',page); alert(message); diff --git a/modules/blog/skins/xe_blog/comment_form.html b/modules/blog/skins/xe_blog/comment_form.html index 93119a91a..53ff5c612 100644 --- a/modules/blog/skins/xe_blog/comment_form.html +++ b/modules/blog/skins/xe_blog/comment_form.html @@ -33,6 +33,7 @@ +
@@ -51,7 +52,7 @@
- +
{$editor?$editor:$comment_editor[$document_srl]}
diff --git a/modules/blog/skins/xe_blog/filter/insert.xml b/modules/blog/skins/xe_blog/filter/insert.xml index 3938eaf42..254dad45d 100644 --- a/modules/blog/skins/xe_blog/filter/insert.xml +++ b/modules/blog/skins/xe_blog/filter/insert.xml @@ -1,6 +1,5 @@ - diff --git a/modules/blog/skins/xe_blog/js/blog.js b/modules/blog/skins/xe_blog/js/blog.js index 01ef837d7..2fd8db522 100644 --- a/modules/blog/skins/xe_blog/js/blog.js +++ b/modules/blog/skins/xe_blog/js/blog.js @@ -26,8 +26,8 @@ function completeDeleteDocument(ret_obj) { var mid = ret_obj['mid']; var page = ret_obj['page']; - var url = "./?mid="+mid; - if(page) url += "&page="+page; + var url = current_url.setQuery('mid',mid).setQuery('act','').setQuery('document_srl',''); + if(page) url = url.setQuery('page',page); alert(message); @@ -73,8 +73,8 @@ function completeDeleteComment(ret_obj) { var document_srl = ret_obj['document_srl']; var page = ret_obj['page']; - var url = "./?mid="+mid+'&document_srl='+document_srl; - if(page) url += "&page="+page; + var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); + if(page) url = url.setQuery('page',page); alert(message); diff --git a/modules/board/board.view.php b/modules/board/board.view.php index d99b839a4..41ed4e42d 100644 --- a/modules/board/board.view.php +++ b/modules/board/board.view.php @@ -180,9 +180,10 @@ $oDocument = $oDocumentModel->getDocument(0, $this->grant->manager); $oDocument->setDocument($document_srl); - if(!$oDocument->isExists()) Context::set('document_srl',''); - - if(!$document_srl) $document_srl = getNextSequence(); + if(!$oDocument->isExists()) { + $document_srl = getNextSequence(); + Context::set('document_srl',$document_srl); + } // 글을 수정하려고 할 경우 권한이 없는 경우 비밀번호 입력화면으로 if($oDocument->isExists()&&!$oDocument->isGranted()) return $this->setTemplateFile('input_password_form'); @@ -192,6 +193,8 @@ // 에디터 모듈의 getEditor를 호출하여 세팅 $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'document_srl'; + $option->content_key_name = 'content'; $option->allow_fileupload = $this->grant->fileupload; $option->enable_autosave = true; $option->enable_default_component = true; @@ -368,14 +371,13 @@ * 댓글의 경우 수정하는 경우가 아니라면 고유값이 없음.\n * 따라서 고유값이 없을 경우 고유값을 가져와서 지정해 주어야 함 **/ - function setCommentEditor($comment_srl=0, $height = 100) { - if(!$comment_srl) { - $comment_srl = getNextSequence(); - Context::set('comment_srl', $comment_srl); - } + function setCommentEditor($comment_srl = 0, $height = 100) { + Context::set('comment_srl', $comment_srl); // 에디터 모듈의 getEditor를 호출하여 세팅 $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'comment_srl'; + $option->content_key_name = 'content'; $option->allow_fileupload = $this->grant->comment_fileupload; $option->enable_autosave = false; $option->enable_default_component = true; diff --git a/modules/board/skins/cozy_simple_gallery/filter/insert.xml b/modules/board/skins/cozy_simple_gallery/filter/insert.xml index 85d1ed4ce..fbfb2d970 100644 --- a/modules/board/skins/cozy_simple_gallery/filter/insert.xml +++ b/modules/board/skins/cozy_simple_gallery/filter/insert.xml @@ -1,6 +1,5 @@ - diff --git a/modules/board/skins/cozy_simple_gallery/js/board.js b/modules/board/skins/cozy_simple_gallery/js/board.js index 304ff69d7..494a561ab 100644 --- a/modules/board/skins/cozy_simple_gallery/js/board.js +++ b/modules/board/skins/cozy_simple_gallery/js/board.js @@ -40,7 +40,7 @@ function completeDeleteDocument(ret_obj) { var page = ret_obj['page']; var url = current_url.setQuery('mid',mid).setQuery('act','').setQuery('document_srl',''); - if(page) url += url.setQuery('page',page); + if(page) url = url.setQuery('page',page); alert(message); @@ -98,7 +98,7 @@ function completeDeleteComment(ret_obj) { var page = ret_obj['page']; var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); - if(page) url += url.setQuery('page',page); + if(page) url = url.setQuery('page',page); alert(message); diff --git a/modules/board/skins/cozy_simple_list/filter/insert.xml b/modules/board/skins/cozy_simple_list/filter/insert.xml index 85d1ed4ce..fbfb2d970 100644 --- a/modules/board/skins/cozy_simple_list/filter/insert.xml +++ b/modules/board/skins/cozy_simple_list/filter/insert.xml @@ -1,6 +1,5 @@ - diff --git a/modules/board/skins/cozy_simple_list/js/board.js b/modules/board/skins/cozy_simple_list/js/board.js index 304ff69d7..494a561ab 100644 --- a/modules/board/skins/cozy_simple_list/js/board.js +++ b/modules/board/skins/cozy_simple_list/js/board.js @@ -40,7 +40,7 @@ function completeDeleteDocument(ret_obj) { var page = ret_obj['page']; var url = current_url.setQuery('mid',mid).setQuery('act','').setQuery('document_srl',''); - if(page) url += url.setQuery('page',page); + if(page) url = url.setQuery('page',page); alert(message); @@ -98,7 +98,7 @@ function completeDeleteComment(ret_obj) { var page = ret_obj['page']; var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); - if(page) url += url.setQuery('page',page); + if(page) url = url.setQuery('page',page); alert(message); diff --git a/modules/board/skins/cozy_simple_webzine/filter/insert.xml b/modules/board/skins/cozy_simple_webzine/filter/insert.xml index 85d1ed4ce..fbfb2d970 100644 --- a/modules/board/skins/cozy_simple_webzine/filter/insert.xml +++ b/modules/board/skins/cozy_simple_webzine/filter/insert.xml @@ -1,6 +1,5 @@ - diff --git a/modules/board/skins/cozy_simple_webzine/js/board.js b/modules/board/skins/cozy_simple_webzine/js/board.js index 304ff69d7..494a561ab 100644 --- a/modules/board/skins/cozy_simple_webzine/js/board.js +++ b/modules/board/skins/cozy_simple_webzine/js/board.js @@ -40,7 +40,7 @@ function completeDeleteDocument(ret_obj) { var page = ret_obj['page']; var url = current_url.setQuery('mid',mid).setQuery('act','').setQuery('document_srl',''); - if(page) url += url.setQuery('page',page); + if(page) url = url.setQuery('page',page); alert(message); @@ -98,7 +98,7 @@ function completeDeleteComment(ret_obj) { var page = ret_obj['page']; var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); - if(page) url += url.setQuery('page',page); + if(page) url = url.setQuery('page',page); alert(message); diff --git a/modules/board/skins/xe_gallery/filter/insert.xml b/modules/board/skins/xe_gallery/filter/insert.xml index 85d1ed4ce..fbfb2d970 100644 --- a/modules/board/skins/xe_gallery/filter/insert.xml +++ b/modules/board/skins/xe_gallery/filter/insert.xml @@ -1,6 +1,5 @@ - diff --git a/modules/board/skins/xe_gallery/js/board.js b/modules/board/skins/xe_gallery/js/board.js index 304ff69d7..494a561ab 100644 --- a/modules/board/skins/xe_gallery/js/board.js +++ b/modules/board/skins/xe_gallery/js/board.js @@ -40,7 +40,7 @@ function completeDeleteDocument(ret_obj) { var page = ret_obj['page']; var url = current_url.setQuery('mid',mid).setQuery('act','').setQuery('document_srl',''); - if(page) url += url.setQuery('page',page); + if(page) url = url.setQuery('page',page); alert(message); @@ -98,7 +98,7 @@ function completeDeleteComment(ret_obj) { var page = ret_obj['page']; var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); - if(page) url += url.setQuery('page',page); + if(page) url = url.setQuery('page',page); alert(message); diff --git a/modules/board/skins/xe_list/filter/insert.xml b/modules/board/skins/xe_list/filter/insert.xml index 85d1ed4ce..fbfb2d970 100644 --- a/modules/board/skins/xe_list/filter/insert.xml +++ b/modules/board/skins/xe_list/filter/insert.xml @@ -1,6 +1,5 @@ - diff --git a/modules/board/skins/xe_list/js/board.js b/modules/board/skins/xe_list/js/board.js index 304ff69d7..494a561ab 100644 --- a/modules/board/skins/xe_list/js/board.js +++ b/modules/board/skins/xe_list/js/board.js @@ -40,7 +40,7 @@ function completeDeleteDocument(ret_obj) { var page = ret_obj['page']; var url = current_url.setQuery('mid',mid).setQuery('act','').setQuery('document_srl',''); - if(page) url += url.setQuery('page',page); + if(page) url = url.setQuery('page',page); alert(message); @@ -98,7 +98,7 @@ function completeDeleteComment(ret_obj) { var page = ret_obj['page']; var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); - if(page) url += url.setQuery('page',page); + if(page) url = url.setQuery('page',page); alert(message); diff --git a/modules/board/skins/xe_webzine/filter/insert.xml b/modules/board/skins/xe_webzine/filter/insert.xml index 85d1ed4ce..fbfb2d970 100644 --- a/modules/board/skins/xe_webzine/filter/insert.xml +++ b/modules/board/skins/xe_webzine/filter/insert.xml @@ -1,6 +1,5 @@ - diff --git a/modules/board/skins/xe_webzine/js/board.js b/modules/board/skins/xe_webzine/js/board.js index 304ff69d7..494a561ab 100644 --- a/modules/board/skins/xe_webzine/js/board.js +++ b/modules/board/skins/xe_webzine/js/board.js @@ -40,7 +40,7 @@ function completeDeleteDocument(ret_obj) { var page = ret_obj['page']; var url = current_url.setQuery('mid',mid).setQuery('act','').setQuery('document_srl',''); - if(page) url += url.setQuery('page',page); + if(page) url = url.setQuery('page',page); alert(message); @@ -98,7 +98,7 @@ function completeDeleteComment(ret_obj) { var page = ret_obj['page']; var url = current_url.setQuery('mid',mid).setQuery('document_srl',document_srl).setQuery('act',''); - if(page) url += url.setQuery('page',page); + if(page) url = url.setQuery('page',page); alert(message); diff --git a/modules/comment/comment.controller.php b/modules/comment/comment.controller.php index 91f3b3225..95d4594b8 100644 --- a/modules/comment/comment.controller.php +++ b/modules/comment/comment.controller.php @@ -56,18 +56,26 @@ $obj->homepage = $logged_info->homepage; } } + + // 댓글 번호가 있으면 첨부파일 조사 + if($obj->comment_srl) { + // file의 Model객체 생성 + $oFileModel = &getModel('file'); + + // 첨부 파일의 갯수를 구함 + $obj->uploaded_count = $oFileModel->getFilesCount($obj->comment_srl); + // 댓글 번호가 없다면 신규 번호 할당 + } else { + $obj->comment_srl = getNextSequence(); + } + + // 순서를 정함 $obj->list_order = $obj->comment_srl * -1; // begin transaction $oDB = &DB::getInstance(); $oDB->begin(); - // file의 Model객체 생성 - $oFileModel = &getModel('file'); - - // 첨부 파일의 갯수를 구함 - $obj->uploaded_count = $oFileModel->getFilesCount($obj->comment_srl); - // 댓글을 입력 $output = executeQuery('comment.insertComment', $obj); diff --git a/modules/comment/lang/ko.lang.php b/modules/comment/lang/ko.lang.php index 26b750520..b980ea3ec 100644 --- a/modules/comment/lang/ko.lang.php +++ b/modules/comment/lang/ko.lang.php @@ -4,6 +4,8 @@ * @author zero * @brief 댓글(comment) 모듈의 기본 언어팩 **/ + + $lang->cmd_toggle_checked_comment = '선택항목 반전'; $lang->cmd_delete_checked_comment = '선택항목 삭제'; $lang->msg_cart_is_null = '삭제할 글을 선택해주세요'; diff --git a/modules/comment/queries/insertComment.xml b/modules/comment/queries/insertComment.xml index 75618f34f..12bed121c 100644 --- a/modules/comment/queries/insertComment.xml +++ b/modules/comment/queries/insertComment.xml @@ -1,23 +1,24 @@ - - - - - - - - - - - - - - - - - - - - - + +
+ + + + + + + + + + + + + + + + + + + + diff --git a/modules/comment/queries/updateComment.xml b/modules/comment/queries/updateComment.xml index 1eb1bbf40..ecc851cc6 100644 --- a/modules/comment/queries/updateComment.xml +++ b/modules/comment/queries/updateComment.xml @@ -1,21 +1,22 @@ - -
- - - - - - - - - - - - - - - - - + +
+ + + + + + + + + + + + + + + + + + diff --git a/modules/comment/tpl/comment_list.html b/modules/comment/tpl/comment_list.html index 33bb15810..2b0d6827c 100644 --- a/modules/comment/tpl/comment_list.html +++ b/modules/comment/tpl/comment_list.html @@ -58,7 +58,9 @@ diff --git a/modules/comment/tpl/js/comment_admin.js b/modules/comment/tpl/js/comment_admin.js index 92eff1785..de3f22c2b 100644 --- a/modules/comment/tpl/js/comment_admin.js +++ b/modules/comment/tpl/js/comment_admin.js @@ -1,6 +1,9 @@ -function doCheckAll() { +function doCheckAll(bToggle) { var fo_obj = xGetElementById('fo_list'); + if(typeof(bToggle) == "undefined") bToggle = false; for(var i=0;i_saved_doc_content); unset($obj->_saved_doc_message); - // file의 Model객체 생성 - $oFileModel = &getModel('file'); + // 문서 번호가 이미 있다면 첨부파일을 확인 + if($obj->document_srl) { + // file의 Model객체 생성 + $oFileModel = &getModel('file'); - // 첨부 파일의 갯수를 구함 - $obj->uploaded_count = $oFileModel->getFilesCount($obj->document_srl); + // 첨부 파일의 갯수를 구함 + $obj->uploaded_count = $oFileModel->getFilesCount($obj->document_srl); + // 문서 번호가 없다면 문서 번호 할당 + } else { + $obj->document_srl = getNextSequence(); + } // 카테고리가 있나 검사하여 없는 카테고리면 0으로 세팅 if($obj->category_srl) { diff --git a/modules/document/document.item.php b/modules/document/document.item.php index 42c723826..619339d5f 100644 --- a/modules/document/document.item.php +++ b/modules/document/document.item.php @@ -153,6 +153,7 @@ $_SESSION['accessible'][$this->document_srl] = true; $content = $this->get('content'); + if($strlen) return cut_str(strip_tags($content),$strlen,'...'); return htmlspecialchars($content); @@ -164,6 +165,9 @@ $_SESSION['accessible'][$this->document_srl] = true; $content = $this->get('content'); + + // OL/LI 태그를 위한 치환 처리 + $content = preg_replace('!<(ol|ul|blockquote)>!is','<\\1 style="margin-left:40px;">',$content); if($add_document_info) return sprintf('%s', $this->document_srl, $this->get('member_srl'), $content, $this->document_srl, $this->get('member_srl')); diff --git a/modules/document/lang/en.lang.php b/modules/document/lang/en.lang.php index 2100a1f6c..44ec73200 100644 --- a/modules/document/lang/en.lang.php +++ b/modules/document/lang/en.lang.php @@ -5,6 +5,7 @@ * @brief Document module's basic language pack **/ + $lang->cmd_toggle_checked_document = '선택항목 반전'; $lang->cmd_delete_checked_document = 'Delete selected'; $lang->msg_cart_is_null = 'Select the articles you wish to delete'; diff --git a/modules/document/lang/es.lang.php b/modules/document/lang/es.lang.php index 137438f5c..18b674152 100644 --- a/modules/document/lang/es.lang.php +++ b/modules/document/lang/es.lang.php @@ -5,6 +5,7 @@ * @sumario Paquete del idioma español para el módulo de documentos. **/ + $lang->cmd_toggle_checked_document = '선택항목 반전'; $lang->cmd_delete_checked_document = 'Eliminar lo seleccionado'; $lang->msg_cart_is_null = 'Selecciona el documento que desea eliminar'; diff --git a/modules/document/lang/jp.lang.php b/modules/document/lang/jp.lang.php index 9d1c3f5b3..47aa81db8 100644 --- a/modules/document/lang/jp.lang.php +++ b/modules/document/lang/jp.lang.php @@ -5,6 +5,7 @@ * @brief ドキュメント(document)モジュルの基本言語パッケージ **/ + $lang->cmd_toggle_checked_document = '선택항목 반전'; $lang->cmd_delete_checked_document = '選択項目削除'; $lang->msg_cart_is_null = '削除する書き込みを選択してください。'; diff --git a/modules/document/lang/ko.lang.php b/modules/document/lang/ko.lang.php index 824ded0f4..2c398727e 100644 --- a/modules/document/lang/ko.lang.php +++ b/modules/document/lang/ko.lang.php @@ -5,6 +5,7 @@ * @brief 문서(document) 모듈의 기본 언어팩 **/ + $lang->cmd_toggle_checked_document = '선택항목 반전'; $lang->cmd_delete_checked_document = '선택항목 삭제'; $lang->msg_cart_is_null = '삭제할 글을 선택해주세요'; diff --git a/modules/document/lang/zh-CN.lang.php b/modules/document/lang/zh-CN.lang.php index 6ebb8499c..2f631d1a9 100644 --- a/modules/document/lang/zh-CN.lang.php +++ b/modules/document/lang/zh-CN.lang.php @@ -5,6 +5,7 @@ * @brief 文章(document)模块语言包 **/ + $lang->cmd_toggle_checked_document = '선택항목 반전'; $lang->cmd_delete_checked_document = '删除所选项目'; $lang->msg_cart_is_null = '请选择要删除的文章。'; diff --git a/modules/document/tpl/document_list.html b/modules/document/tpl/document_list.html index 0c3e9eed2..f07b846d0 100644 --- a/modules/document/tpl/document_list.html +++ b/modules/document/tpl/document_list.html @@ -62,6 +62,8 @@ diff --git a/modules/document/tpl/js/document_admin.js b/modules/document/tpl/js/document_admin.js index 92eff1785..de3f22c2b 100644 --- a/modules/document/tpl/js/document_admin.js +++ b/modules/document/tpl/js/document_admin.js @@ -1,6 +1,9 @@ -function doCheckAll() { +function doCheckAll(bToggle) { var fo_obj = xGetElementById('fo_list'); + if(typeof(bToggle) == "undefined") bToggle = false; for(var i=0;iupload_target_srl = $upload_target_srl; + function colorpicker_bg($editor_sequence, $component_path) { + $this->editor_sequence = $editor_sequence; $this->component_path = $component_path; } diff --git a/modules/editor/components/colorpicker_text/colorpicker_text.class.php b/modules/editor/components/colorpicker_text/colorpicker_text.class.php index 7ded73448..8e2ebf911 100644 --- a/modules/editor/components/colorpicker_text/colorpicker_text.class.php +++ b/modules/editor/components/colorpicker_text/colorpicker_text.class.php @@ -7,15 +7,15 @@ class colorpicker_text extends EditorHandler { - // upload_target_srl 는 에디터에서 필수로 달고 다녀야 함.... - var $upload_target_srl = 0; + // editor_sequence 는 에디터에서 필수로 달고 다녀야 함.... + var $editor_sequence = 0; var $component_path = ''; /** - * @brief upload_target_srl과 컴포넌트의 경로를 받음 + * @brief editor_sequence과 컴포넌트의 경로를 받음 **/ - function colorpicker_text($upload_target_srl, $component_path) { - $this->upload_target_srl = $upload_target_srl; + function colorpicker_text($editor_sequence, $component_path) { + $this->editor_sequence = $editor_sequence; $this->component_path = $component_path; } diff --git a/modules/editor/components/emoticon/emoticon.class.php b/modules/editor/components/emoticon/emoticon.class.php index be706e193..7f4eb108e 100644 --- a/modules/editor/components/emoticon/emoticon.class.php +++ b/modules/editor/components/emoticon/emoticon.class.php @@ -7,15 +7,15 @@ class emoticon extends EditorHandler { - // upload_target_srl 는 에디터에서 필수로 달고 다녀야 함.... - var $upload_target_srl = 0; + // editor_sequence 는 에디터에서 필수로 달고 다녀야 함.... + var $editor_sequence = 0; var $component_path = ''; /** - * @brief upload_target_srl과 컴포넌트의 경로를 받음 + * @brief editor_sequence과 컴포넌트의 경로를 받음 **/ - function emoticon($upload_target_srl, $component_path) { - $this->upload_target_srl = $upload_target_srl; + function emoticon($editor_sequence, $component_path) { + $this->editor_sequence = $editor_sequence; $this->component_path = $component_path; } diff --git a/modules/editor/components/image_gallery/image_gallery.class.php b/modules/editor/components/image_gallery/image_gallery.class.php index b12e8f8b1..2a7bd8495 100644 --- a/modules/editor/components/image_gallery/image_gallery.class.php +++ b/modules/editor/components/image_gallery/image_gallery.class.php @@ -7,15 +7,15 @@ class image_gallery extends EditorHandler { - // upload_target_srl 는 에디터에서 필수로 달고 다녀야 함.... - var $upload_target_srl = 0; + // editor_sequence 는 에디터에서 필수로 달고 다녀야 함.... + var $editor_sequence = 0; var $component_path = ''; /** - * @brief upload_target_srl과 컴포넌트의 경로를 받음 + * @brief editor_sequence과 컴포넌트의 경로를 받음 **/ - function image_gallery($upload_target_srl, $component_path) { - $this->upload_target_srl = $upload_target_srl; + function image_gallery($editor_sequence, $component_path) { + $this->editor_sequence = $editor_sequence; $this->component_path = $component_path; } diff --git a/modules/editor/components/image_gallery/tpl/popup.html b/modules/editor/components/image_gallery/tpl/popup.html index 1ac863546..06459ba1e 100644 --- a/modules/editor/components/image_gallery/tpl/popup.html +++ b/modules/editor/components/image_gallery/tpl/popup.html @@ -7,7 +7,7 @@
- +
diff --git a/modules/editor/components/image_gallery/tpl/popup.js b/modules/editor/components/image_gallery/tpl/popup.js index 095b72977..2acd50199 100644 --- a/modules/editor/components/image_gallery/tpl/popup.js +++ b/modules/editor/components/image_gallery/tpl/popup.js @@ -39,9 +39,9 @@ function getSlideShow() { // 부모창의 업로드된 파일중 이미지 목록을 모두 가져와서 세팅 var fo = xGetElementById("fo"); - var upload_target_srl = fo.upload_target_srl.value; + var editor_sequence = fo.editor_sequence.value; - var parent_list_obj = opener.xGetElementById("uploaded_file_list_"+upload_target_srl); + var parent_list_obj = opener.xGetElementById("uploaded_file_list_"+editor_sequence); if(parent_list_obj) { var list_obj = xGetElementById("image_list"); diff --git a/modules/editor/components/image_link/image_link.class.php b/modules/editor/components/image_link/image_link.class.php index 8a3d2a89f..521bfdab1 100644 --- a/modules/editor/components/image_link/image_link.class.php +++ b/modules/editor/components/image_link/image_link.class.php @@ -7,15 +7,15 @@ class image_link extends EditorHandler { - // upload_target_srl 는 에디터에서 필수로 달고 다녀야 함.... - var $upload_target_srl = 0; + // editor_sequence 는 에디터에서 필수로 달고 다녀야 함.... + var $editor_sequence = 0; var $component_path = ''; /** - * @brief upload_target_srl과 컴포넌트의 경로를 받음 + * @brief editor_sequence과 컴포넌트의 경로를 받음 **/ - function image_link($upload_target_srl, $component_path) { - $this->upload_target_srl = $upload_target_srl; + function image_link($editor_sequence, $component_path) { + $this->editor_sequence = $editor_sequence; $this->component_path = $component_path; } diff --git a/modules/editor/components/multimedia_link/multimedia_link.class.php b/modules/editor/components/multimedia_link/multimedia_link.class.php index e1f0b5ba3..65d345812 100644 --- a/modules/editor/components/multimedia_link/multimedia_link.class.php +++ b/modules/editor/components/multimedia_link/multimedia_link.class.php @@ -7,15 +7,15 @@ class multimedia_link extends EditorHandler { - // upload_target_srl 는 에디터에서 필수로 달고 다녀야 함.... - var $upload_target_srl = 0; + // editor_sequence 는 에디터에서 필수로 달고 다녀야 함.... + var $editor_sequence = 0; var $component_path = ''; /** - * @brief upload_target_srl과 컴포넌트의 경로를 받음 + * @brief editor_sequence과 컴포넌트의 경로를 받음 **/ - function multimedia_link($upload_target_srl, $component_path) { - $this->upload_target_srl = $upload_target_srl; + function multimedia_link($editor_sequence, $component_path) { + $this->editor_sequence = $editor_sequence; $this->component_path = $component_path; } diff --git a/modules/editor/components/poll_maker/poll_maker.class.php b/modules/editor/components/poll_maker/poll_maker.class.php index 7b559fd56..dda44c901 100644 --- a/modules/editor/components/poll_maker/poll_maker.class.php +++ b/modules/editor/components/poll_maker/poll_maker.class.php @@ -7,15 +7,15 @@ class poll_maker extends EditorHandler { - // upload_target_srl 는 에디터에서 필수로 달고 다녀야 함.... - var $upload_target_srl = 0; + // editor_sequence 는 에디터에서 필수로 달고 다녀야 함.... + var $editor_sequence = 0; var $component_path = ''; /** - * @brief upload_target_srl과 컴포넌트의 경로를 받음 + * @brief editor_sequence과 컴포넌트의 경로를 받음 **/ - function poll_maker($upload_target_srl, $component_path) { - $this->upload_target_srl = $upload_target_srl; + function poll_maker($editor_sequence, $component_path) { + $this->editor_sequence = $editor_sequence; $this->component_path = $component_path; } diff --git a/modules/editor/components/poll_maker/tpl/popup.html b/modules/editor/components/poll_maker/tpl/popup.html index fb1abeda7..c04ef50ab 100644 --- a/modules/editor/components/poll_maker/tpl/popup.html +++ b/modules/editor/components/poll_maker/tpl/popup.html @@ -15,7 +15,7 @@ - +
diff --git a/modules/editor/components/quotation/quotation.class.php b/modules/editor/components/quotation/quotation.class.php index c93b53d76..2e60de13d 100644 --- a/modules/editor/components/quotation/quotation.class.php +++ b/modules/editor/components/quotation/quotation.class.php @@ -7,15 +7,15 @@ class quotation extends EditorHandler { - // upload_target_srl 는 에디터에서 필수로 달고 다녀야 함.... - var $upload_target_srl = 0; + // editor_sequence 는 에디터에서 필수로 달고 다녀야 함.... + var $editor_sequence = 0; var $component_path = ''; /** - * @brief upload_target_srl과 컴포넌트의 경로를 받음 + * @brief editor_sequence과 컴포넌트의 경로를 받음 **/ - function quotation($upload_target_srl, $component_path) { - $this->upload_target_srl = $upload_target_srl; + function quotation($editor_sequence, $component_path) { + $this->editor_sequence = $editor_sequence; $this->component_path = $component_path; } diff --git a/modules/editor/components/table_maker/table_maker.class.php b/modules/editor/components/table_maker/table_maker.class.php index 6b87d2758..3eddb7878 100644 --- a/modules/editor/components/table_maker/table_maker.class.php +++ b/modules/editor/components/table_maker/table_maker.class.php @@ -7,15 +7,15 @@ class table_maker extends EditorHandler { - // upload_target_srl 는 에디터에서 필수로 달고 다녀야 함.... - var $upload_target_srl = 0; + // editor_sequence 는 에디터에서 필수로 달고 다녀야 함.... + var $editor_sequence = 0; var $component_path = ''; /** - * @brief upload_target_srl과 컴포넌트의 경로를 받음 + * @brief editor_sequence과 컴포넌트의 경로를 받음 **/ - function table_maker($upload_target_srl, $component_path) { - $this->upload_target_srl = $upload_target_srl; + function table_maker($editor_sequence, $component_path) { + $this->editor_sequence = $editor_sequence; $this->component_path = $component_path; } diff --git a/modules/editor/components/url_link/url_link.class.php b/modules/editor/components/url_link/url_link.class.php index 2f8fc7211..3f8ae3429 100644 --- a/modules/editor/components/url_link/url_link.class.php +++ b/modules/editor/components/url_link/url_link.class.php @@ -7,15 +7,15 @@ class url_link extends EditorHandler { - // upload_target_srl 는 에디터에서 필수로 달고 다녀야 함.... - var $upload_target_srl = 0; + // editor_sequence 는 에디터에서 필수로 달고 다녀야 함.... + var $editor_sequence = 0; var $component_path = ''; /** - * @brief upload_target_srl과 컴포넌트의 경로를 받음 + * @brief editor_sequence과 컴포넌트의 경로를 받음 **/ - function url_link($upload_target_srl, $component_path) { - $this->upload_target_srl = $upload_target_srl; + function url_link($editor_sequence, $component_path) { + $this->editor_sequence = $editor_sequence; $this->component_path = $component_path; } diff --git a/modules/editor/editor.controller.php b/modules/editor/editor.controller.php index 151f0ba8d..3e82f963c 100644 --- a/modules/editor/editor.controller.php +++ b/modules/editor/editor.controller.php @@ -31,12 +31,8 @@ $args->ipaddress = $_SERVER['REMOTE_ADDR']; } - // 필요한 데이터가 없으면 pass - if(!$args->document_srl || (!$args->title && !$args->content)) return new Object(0,''); - // 저장 $output = executeQuery('editor.insertSavedDoc', $args); - $this->setMessage('msg_auto_saved'); } diff --git a/modules/editor/editor.model.php b/modules/editor/editor.model.php index 206f03f0f..3e08b972b 100644 --- a/modules/editor/editor.model.php +++ b/modules/editor/editor.model.php @@ -11,13 +11,30 @@ /** * @brief 에디터를 return + * + * 에디터의 경우 내부적으로 1~30까지의 임시 editor_seuqnece를 생성한다. + * 즉 한페이지에 30개 이상의 에디터를 출력하지는 못하도록 제한되어 있다. + * + * 단, 수정하는 경우 또는 파일업로드를 한 자동저장본의 경우는 getNextSequence() 값으로 저장된 editor_seqnece가 + * 설정된다. + * + * editor_sequence <= 30 일경우에는 무조건 가상의 번호로 판별함 **/ - function getEditor($upload_target_srl, $option = null) { + + /** + * 에디터 template을 return + * upload_target_srl은 글의 수정시 호출하면 됨. + * 이 upload_target_srl은 첨부파일의 유무를 체크하기 위한 루틴을 구현하는데 사용됨. + **/ + function getEditor($upload_target_srl = 0, $option = null) { + /** + * 기본적인 에디터의 옵션을 정리 + **/ // 파일 업로드 유무 옵션 설정 if(!$option->allow_fileupload) $allow_fileupload = false; else $allow_fileupload = true; - // 자동 저장 유무 옵션 설정 + // 자동 저장 유무 옵션 설정 if(!$option->enable_autosave) $enable_autosave = false; else $enable_autosave = true; @@ -41,35 +58,68 @@ if(!$option->skin) $skin = 'default'; else $skin = $option->skin; - // 대상 문서 번호 설정 - Context::set('upload_target_srl', $upload_target_srl); + /** + * 자동백업 기능 체크 (글 수정일 경우는 사용하지 않음) + **/ + if(!$upload_target_srl && $enable_autosave) { + // 자동 저장된 데이터를 추출 + $saved_doc = $this->getSavedDoc(); - // 업로드 가능 변수 설정 - if($allow_fileupload) { - // 첨부파일 모듈의 정보를 구함 - $logged_info = Context::get('logged_info'); - if($logged_info->member_srl && $logged_info->is_admin == 'Y') { - $file_config->allowed_filesize = 1024*1024*1024; - $file_config->allowed_attach_size = 1024*1024*1024; - $file_config->allowed_filetypes = '*.*'; - } else { - $oModuleModel = &getModel('module'); - $file_config = $oModuleModel->getModuleConfig('file'); - $file_config->allowed_filesize = $file_config->allowed_filesize * 1024; - $file_config->allowed_attach_size = $file_config->allowed_attach_size * 1024; - } - Context::set('file_config',$file_config); - } - Context::set('allow_fileupload', $allow_fileupload); + // 자동저장된 데이터에 실제하는 문서 번호가 있다면 해당 문서 번호를 세팅 + if($saved_doc->document_srl) $upload_target_srl = $saved_doc->upload_target_srl; - // 자동백업 기능 체크 - if($enable_autosave) { - $saved_doc = $this->getSavedDoc($upload_target_srl); + // 자동 저장 데이터를 context setting Context::set('saved_doc', $saved_doc); } Context::set('enable_autosave', $enable_autosave); - // 에디터 컴포넌트 체크 + /** + * 에디터의 고유 번호 추출 (한 페이지에 여러개의 에디터를 출력하는 경우를 대비) + **/ + if($option->editor_sequence) $editor_sequence = $option->editor_sequence; + else { + if(!$GLOBALS['_editor_sequence_']) $GLOBALS['_editor_sequence_'] = 1; + $editor_sequence = $GLOBALS['_editor_sequence_'] ++; + } + + /** + * 업로드 활성화시 내부적으로 file 모듈의 환경설정을 이용하여 설정 + **/ + if($allow_fileupload) { + $oFileModel = &getModel('file'); + + // SWFUploader에 세팅할 업로드 설정 구함 + $file_config = $oFileModel->getUploadConfig(); + $file_config->attached_size = FileHandler::filesize($file_config->allowed_attach_size*1024*1024); + $file_config->allowed_filesize = FileHandler::filesize($file_config->allowed_filesize*1024*1024); + Context::set('file_config',$file_config); + + // 업로드 가능 용량등에 대한 정보를 세팅 + $upload_status = $oFileModel->getUploadStatus(); + Context::set('upload_status', $upload_status); + + // upload가능하다고 설정 (내부적으로 캐싱하여 처리) + $oFileController = &getController('file'); + $oFileController->setUploadInfo($editor_sequence, $upload_target_srl); + } + Context::set('allow_fileupload', $allow_fileupload); + + // 에디터 동작을 위한 editor_sequence값 설정 + Context::set('editor_sequence', $editor_sequence); + + // 파일 첨부 관련 행동을 하기 위해 문서 번호를 upload_target_srl로 설정 + // 신규문서일 경우 upload_target_srl=0 이고 첨부파일 관련 동작이 요청될때 이 값이 변경됨 + Context::set('upload_target_srl', $upload_target_srl); + + // 문서 혹은 댓글의 primary key값을 세팅한다. + Context::set('editor_primary_key_name', $option->primary_key_name); + + // 내용을 sync 맞추기 위한 content column name을 세팅한다 + Context::set('editor_content_key_name', $option->content_key_name); + + /** + * 에디터 컴포넌트 체크 + **/ if($enable_component) { if(!Context::get('component_list')) { $component_list = $this->getComponentList(); @@ -79,24 +129,24 @@ Context::set('enable_component', $enable_component); Context::set('enable_default_component', $enable_default_component); - // resizable 가능한지 변수 설정 + /** + * resizable 가능한지 변수 설정 + **/ Context::set('enable_resizable', $resizable); - // 에디터 크기 설정 + /** + * 에디터 세로 크기 설정 + **/ Context::set('editor_height', $editor_height); - // 템플릿을 미리 컴파일해서 컴파일된 소스를 return + /** + * 템플릿을 미리 컴파일해서 컴파일된 소스를 하기 위해 스킨의 경로를 설정 + **/ $tpl_path = sprintf('%sskins/%s/', $this->module_path, $skin); $tpl_file = 'editor.html'; - - // editor_path를 지정 Context::set('editor_path', $tpl_path); - // 만약 allow_fileupload == true 이면 upload_target_srl에 upload가능하다고 설정 - if($allow_fileupload) { - $oFileController = &getController('file'); - $oFileController->setUploadEnable($upload_target_srl); - } + // tpl 파일을 compile한 결과를 return $oTemplate = &TemplateHandler::getInstance(); return $oTemplate->compile($tpl_path, $tpl_file); } @@ -104,7 +154,7 @@ /** * @brief 자동저장되어 있는 정보를 가져옴 **/ - function getSavedDoc($upload_target_srl) { + function getSavedDoc() { // 로그인 회원이면 member_srl, 아니면 ipaddress로 저장되어 있는 문서를 찾음 if(Context::get('is_logged')) { $logged_info = Context::get('logged_info'); @@ -113,17 +163,19 @@ $auto_save_args->ipaddress = $_SERVER['REMOTE_ADDR']; } + // DB에서 자동저장 데이터 추출 $output = executeQuery('editor.getSavedDocument', $auto_save_args); $saved_doc = $output->data; + + // 자동저장한 결과가 없으면 null값 return if(!$saved_doc) return; - // 원본 글이 저장되어 있지 않은 글일 경우 첨부된 파일이 있으면 현재 글 번호로 옮김 - $oDocumentModel = &getModel('document'); - $document = $oDocumentModel->getDocument($saved_doc->document_srl); - if($document->document_srl != $saved_doc->document_srl) { + // 자동저장 데이터에 문서번호가 있고 이 번호에 파일이 있다면 파일을 모두 이동하고 + // 해당 문서 번호를 editor_sequence로 세팅함 + if($saved_doc->document_srl) { $module_srl = Context::get('module_srl'); $oFileController = &getController('file'); - $oFileController->moveFile($saved_doc->document_srl, $module_srl, $upload_target_srl); + $oFileController->moveFile($saved_doc->document_srl, $module_srl, $saved_doc->document_srl); } return $saved_doc; @@ -132,8 +184,8 @@ /** * @brief component의 객체 생성 **/ - function getComponentObject($component, $upload_target_srl = 0) { - if(!$this->loaded_component_list[$component][$upload_target_srl]) { + function getComponentObject($component, $editor_sequence = 0) { + if(!$this->loaded_component_list[$component][$editor_sequence]) { // 해당 컴포넌트의 객체를 생성해서 실행 $class_path = sprintf('%scomponents/%s/', $this->module_path, $component); $class_file = sprintf('%s%s.class.php', $class_path, $component); @@ -141,17 +193,17 @@ // 클래스 파일을 읽은 후 객체 생성 require_once($class_file); - $eval_str = sprintf('$oComponent = new %s("%s","%s");', $component, $upload_target_srl, $class_path); + $eval_str = sprintf('$oComponent = new %s("%s","%s");', $component, $editor_sequence, $class_path); @eval($eval_str); if(!$oComponent) return new Object(-1, sprintf(Context::getLang('msg_component_is_not_founded'), $component)); // 설정 정보를 추가 $component_info = $this->getComponent($component); $oComponent->setInfo($component_info); - $this->loaded_component_list[$component][$upload_target_srl] = $oComponent; + $this->loaded_component_list[$component][$editor_sequence] = $oComponent; } - return $this->loaded_component_list[$component][$upload_target_srl]; + return $this->loaded_component_list[$component][$editor_sequence]; } /** diff --git a/modules/editor/editor.view.php b/modules/editor/editor.view.php index e2c7807c8..a08985c6d 100644 --- a/modules/editor/editor.view.php +++ b/modules/editor/editor.view.php @@ -21,12 +21,12 @@ Context::addCssFile($this->module_path."tpl/css/editor.css"); // 변수 정리 - $upload_target_srl = Context::get('upload_target_srl'); + $editor_sequence = Context::get('editor_sequence '); $component = Context::get('component'); // component 객체를 받음 $oEditorModel = &getModel('editor'); - $oComponent = &$oEditorModel->getComponentObject($component, $upload_target_srl); + $oComponent = &$oEditorModel->getComponentObject($component, $editor_sequence); if(!$oComponent->toBool()) { Context::set('message', sprintf(Context::getLang('msg_component_is_not_founded'), $component)); $this->setTemplatePath($this->module_path.'tpl'); diff --git a/modules/editor/lang/ko.lang.php b/modules/editor/lang/ko.lang.php index 4d0519454..d2e4abf60 100644 --- a/modules/editor/lang/ko.lang.php +++ b/modules/editor/lang/ko.lang.php @@ -54,6 +54,10 @@ $lang->edit->submit = '확인'; + $lang->edit->help_remove_format = "선택된 영역 내의 태그를 지웁니다"; + $lang->edit->help_strike_through = "글자에 취소선을 표시합니다"; + $lang->edit->help_align_full = "좌우 폭에 맞게 정렬을 합니다"; + $lang->edit->help_fontcolor = "글자의 색상을 지정합니다"; $lang->edit->help_fontbgcolor = "글자의 배경색상을 지정합니다"; $lang->edit->help_bold = "글자를 진하게 합니다"; diff --git a/modules/editor/skins/default/editor.html b/modules/editor/skins/default/editor.html index 67335a371..b2722592a 100644 --- a/modules/editor/skins/default/editor.html +++ b/modules/editor/skins/default/editor.html @@ -8,7 +8,7 @@ @@ -21,21 +21,21 @@
-
+
- - @@ -46,7 +46,7 @@ - @@ -55,33 +55,35 @@
- {$lang->edit->help_bold} - {$lang->edit->help_italic} - {$lang->edit->help_underline} - {$lang->edit->help_fontcolor} - {$lang->edit->help_fontbgcolor} + {$lang->edit->help_bold} + {$lang->edit->help_italic} + {$lang->edit->help_underline} + {$lang->edit->help_underline} + {$lang->edit->help_underline} + {$lang->edit->help_fontcolor} + {$lang->edit->help_fontbgcolor}
- {$lang->edit->help_align_left} - {$lang->edit->help_align_center} - {$lang->edit->help_align_right} - + {$lang->edit->help_align_left} + {$lang->edit->help_align_center} + {$lang->edit->help_align_right} + {$lang->edit->help_align_full} +
+ +
+ {$lang->edit->help_remove_indent} + {$lang->edit->help_add_indent} +
+ +
+ {$lang->edit->help_list_number} + {$lang->edit->help_list_bullet}
-
+
- {$component->title} + {$component->title}
@@ -115,50 +117,52 @@
-
+ +
{$lang->about_dblclick_in_editor} - - close + + close
+
- +
-
 
+
 
-
- + +
+ -
+ +
- - - diff --git a/modules/editor/skins/default/images/editor_btn_removeformat.gif b/modules/editor/skins/default/images/editor_btn_removeformat.gif new file mode 100644 index 000000000..a53b49625 Binary files /dev/null and b/modules/editor/skins/default/images/editor_btn_removeformat.gif differ diff --git a/modules/editor/skins/default/images/editor_btn_strikethrough.gif b/modules/editor/skins/default/images/editor_btn_strikethrough.gif new file mode 100644 index 000000000..cdae068ea Binary files /dev/null and b/modules/editor/skins/default/images/editor_btn_strikethrough.gif differ diff --git a/modules/editor/tpl/js/editor.js b/modules/editor/tpl/js/editor.js index 04a48c5eb..5971f387b 100755 --- a/modules/editor/tpl/js/editor.js +++ b/modules/editor/tpl/js/editor.js @@ -4,193 +4,57 @@ * @brief 에디터 관련 스크립트 **/ -// iframe의 id prefix -var iframe_id = 'editor_iframe_'; -var textarea_id = 'editor_textarea_'; +/** + * 에디터에서 사용하는 iframe, textarea의 prefix + **/ +var iframe_id = 'editor_iframe_'; ///< 에디터로 사용하는 iframe의 prefix +var textarea_id = 'editor_textarea_'; ///< 에디터의 html편집 모드에서 사용하는 textarea의 prefix +var editor_mode = new Array(); ///<< 에디터의 html편집 모드 flag 세팅 변수 +var _editorSyncList = new Array(); ///< 에디터와 form 동기화를 위한 동기화 대상 목록 +var _autoSaveObj = {fo_obj:null, editor_sequence:0, title:'', content:'', locked:false} ///< 자동저장을 위한 정보를 가진 object +var editor_rel_keys = new Array(); ///< 에디터와 각 모듈과의 연동을 위한 key 값을 보관하는 변수 -// upload_target_srl에 대한 form문을 객체로 보관함 -var editor_form_list = new Array(); +/** + * 에디터 사용시 사용되는 이벤트 연결 함수 호출 + **/ +xAddEventListener(window, 'load', _editorSync); ///< 에디터의 동기화를 하는 함수를 window.load시 실행 -// 편집 상태에 대한 체크 -var editor_mode = new Array(); -// upload_target_srl값에 해당하는 iframe의 object를 return -function editorGetIFrame(upload_target_srl) { - var obj_id = iframe_id+upload_target_srl; + +/** + * 에디터의 상태나 객체를 구하기 위한 함수 + **/ + +// editor_sequence값에 해당하는 iframe의 object를 return +function editorGetIFrame(editor_sequence) { + var obj_id = iframe_id + editor_sequence; return xGetElementById(obj_id); } -// upload_target_srl값에 해당하는 textarea object를 return -function editorGetTextArea(upload_target_srl) { - var obj_id = textarea_id+upload_target_srl; +// editor_sequence값에 해당하는 textarea object를 return +function editorGetTextArea(editor_sequence) { + var obj_id = textarea_id + editor_sequence; return xGetElementById(obj_id); } -// editor 시작 (upload_target_srl로 iframe객체를 얻어서 쓰기 모드로 전환) -function editorStart(upload_target_srl, resizable, editor_height) { - if(typeof(resizable)=="undefined"||!resizable) resizable = false; - else resizable = true; - - // iframe obj를 찾음 - var iframe_obj = editorGetIFrame(upload_target_srl); +// editor_sequence에 해당하는 form문 구함 +function editorGetForm(editor_sequence) { + var iframe_obj = editorGetIFrame(editor_sequence); if(!iframe_obj) return; - iframe_obj.style.width = '100%'; - - // 현 에디터를 감싸고 있는 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" ) { - var saved_title = fo_obj._saved_doc_title.value; - var saved_content = fo_obj._saved_doc_content.value; - if(saved_title || saved_content) { - if(confirm(fo_obj._saved_doc_message.value)) { - fo_obj.title.value = saved_title; - fo_obj.content.value = saved_content; - } else { - editorRemoveSavedDoc(); - } - } - } - - // 구해진 form 객체를 저장 - editor_form_list[upload_target_srl] = fo_obj; - - // 대상 form의 content object에서 데이터를 구함 - var content = fo_obj.content.value; - if(!content && !xIE4Up) content = "
"; - - // iframe내의 document object - var contentDocument = iframe_obj.contentWindow.document; - - // 기본 내용 작성 - var contentHtml = ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - ''+ - content+ - ''+ - ''; - contentDocument.designMode = 'on'; - try { - contentDocument.execCommand("undo", false, null); - contentDocument.execCommand("useCSS", false, true); - } catch (e) { - } - contentDocument.open("text/html","replace"); - contentDocument.write(contentHtml); - contentDocument.close(); - - // 작성시 필요한 이벤트 체크 - if(xIE4Up) xAddEventListener(contentDocument, 'keydown',editorKeyPress); - else xAddEventListener(contentDocument, 'keypress',editorKeyPress); - xAddEventListener(contentDocument,'mousedown',editorHideObject); - - // 위젯 감시를 위한 더블클릭 이벤트 걸기 (오페라에 대한 처리는 차후에.. 뭔가 이상함) - xAddEventListener(contentDocument,'dblclick',editorSearchComponent); - xAddEventListener(document,'dblclick',editorSearchComponent); - - xAddEventListener(document,'mouseup',editorEventCheck); - xAddEventListener(document,'mousedown',editorHideObject); - - if(xIE4Up && xGetElementById('for_ie_help_'+upload_target_srl)) { - xGetElementById('for_ie_help_'+upload_target_srl).style.display = "block"; - } - - // 에디터의 내용을 지속적으로 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); - - // 크기 변경 불가일 경우 드래그바 숨김 - if(resizable == false) xGetElementById("editor_drag_bar_"+upload_target_srl).style.display = "none"; - + if(fo_obj.nodeName == 'FORM') return fo_obj; + return; } -// 여러개의 편집기를 예상하여 전역 배열 변수에 form, iframe의 정보를 넣음 -var _editorSyncList = new Array(); -function editorSyncContent(obj, upload_target_srl) { - _editorSyncList[_editorSyncList.length] = {field:obj, upload_target_srl:upload_target_srl} -} - -// 편집기와 폼의 정보를 주기적으로 동기화 시킴 -function _editorSync() { - for(var i=0;i<_editorSyncList.length;i++) { - var field = _editorSyncList[i].field; - var upload_target_srl = _editorSyncList[i].upload_target_srl; - var content = editorGetContent(upload_target_srl); - if(typeof(content)=='undefined') continue; - field.value = content; - } - setTimeout(_editorSync, 1000); -} -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((fo_obj.title && 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; - - var obj = xGetElementById("editor_autosaved_message_"+upload_target_srl); - var oDate = new Date(); - html = oDate.getHours()+':'+oDate.getMinutes()+' '+auto_saved_msg; - xInnerHtml(obj, html); - obj.style.display = "block"; - - show_waiting_message = false; - exec_xml("editor","procEditorSaveDoc", params, _editorAutoSaved); - show_waiting_message = true; - return; - } - } - - setTimeout(_editorAutoSave, 15000); -} - -function _editorAutoSaved(ret_obj) { - setTimeout(_editorAutoSave, 15000); - return null; -} - -function editorRemoveSavedDoc() { - exec_xml("editor","procEditorRemoveSavedDoc"); -} - -// 에디터의 전체 내용 return -function editorGetContent(upload_target_srl) { - var iframe_obj = editorGetIFrame(upload_target_srl); +// 에디터의 전체 내용 return, HTML 편집모드일 경우에 데이터를 이전후 값 return +function editorGetContent(editor_sequence) { + var iframe_obj = editorGetIFrame(editor_sequence); if(!iframe_obj) return null; var html = null; - if(editor_mode[upload_target_srl]=='html') { - var textarea_obj = editorGetTextArea(upload_target_srl); + if(editor_mode[editor_sequence]=='html') { + var textarea_obj = editorGetTextArea(editor_sequence); var html = textarea_obj.value; var contentDocument = iframe_obj.contentWindow.document; contentDocument.body.innerHTML = html; @@ -202,8 +66,8 @@ function editorGetContent(upload_target_srl) { } // 에디터 내의 선택된 부분의 html 코드를 return -function editorGetSelectedHtml(upload_target_srl) { - var iframe_obj = editorGetIFrame(upload_target_srl); +function editorGetSelectedHtml(editor_sequence) { + var iframe_obj = editorGetIFrame(editor_sequence); if(xIE4Up) { var range = iframe_obj.contentWindow.document.selection.createRange(); var html = range.htmlText; @@ -219,8 +83,8 @@ function editorGetSelectedHtml(upload_target_srl) { } // 에디터 내의 선택된 부분의 NODE를 return -function editorGetSelectedNode(upload_target_srl) { - var iframe_obj = editorGetIFrame(upload_target_srl); +function editorGetSelectedNode(editor_sequence) { + var iframe_obj = editorGetIFrame(editor_sequence); if(xIE4Up) { var range = iframe_obj.contentWindow.document.selection.createRange(); var div = xCreateElement('div'); @@ -235,6 +99,218 @@ function editorGetSelectedNode(upload_target_srl) { } } + +/** + * editor 시작 (editor_sequence로 iframe객체를 얻어서 쓰기 모드로 전환) + **/ +function editorStart(editor_sequence, primary_key, content_key, resizable, editor_height) { + // resize 가/불가에 대한 체크 + if(typeof(resizable)=="undefined"||!resizable) resizable = false; + else resizable = true; + + // iframe obj를 찾음 + var iframe_obj = editorGetIFrame(editor_sequence); + if(!iframe_obj) return; + iframe_obj.style.width = '100%'; ///<< iframe_obj의 가로 크기를 100%로 고정 + + // 현 에디터를 감싸고 있는 form문을 찾아서 content object를 찾아서 내용 sync + var fo_obj = editorGetForm(editor_sequence); + if(!fo_obj) return; + + // 모듈 연관 키 값을 세팅 + editor_rel_keys[editor_sequence] = new Array(); + editor_rel_keys[editor_sequence]["primary"] = fo_obj[primary_key]; + editor_rel_keys[editor_sequence]["content"] = fo_obj[content_key]; + + // saved document(자동저장 문서)에 대한 확인 + if(typeof(fo_obj._saved_doc_title)!="undefined" ) { ///<< _saved_doc_title field가 없으면 자동저장 하지 않음 + + var saved_title = fo_obj._saved_doc_title.value; + var saved_content = fo_obj._saved_doc_content.value; + + if(saved_title || saved_content) { + // 자동저장된 문서 활용여부를 물은 후 사용하지 않는다면 자동저장된 문서 삭제 + if(confirm(fo_obj._saved_doc_message.value)) { + if(typeof(fo_obj.title)!='undefined') fo_obj.title.value = saved_title; + editor_rel_keys[editor_sequence]['content'].value = saved_content; + } else { + editorRemoveSavedDoc(); + } + } + } + + // 대상 form의 content element에서 데이터를 구함 + var content = editor_rel_keys[editor_sequence]['content'].value; + + // IE가 아니고 내용이 없으면
추가 (FF등에서 iframe 선택시 focus를 주기 위한 꽁수) + if(!content && !xIE4Up) content = "
"; + + // iframe내의 document element를 구함 + var contentDocument = iframe_obj.contentWindow.document; + + /** + * 에디터를 위지윅 모드로 만들기 위해 내용 작성 후 designMode 활성화 + **/ + var contentHtml = ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + ''+ + content+ + ''+ + ''; + contentDocument.designMode = 'on'; + try { + contentDocument.execCommand("undo", false, null); + contentDocument.execCommand("useCSS", false, true); + } catch (e) { + } + contentDocument.open("text/html","replace"); + contentDocument.write(contentHtml); + contentDocument.close(); + + /** + * 더블클릭이나 키눌림등의 각종 이벤트에 대해 listener 추가 + **/ + // 작성시 필요한 이벤트 체크 + if(xIE4Up) xAddEventListener(contentDocument, 'keydown',editorKeyPress); + else xAddEventListener(contentDocument, 'keypress',editorKeyPress); + xAddEventListener(contentDocument,'mousedown',editorHideObject); + + // 위젯 감시를 위한 더블클릭 이벤트 걸기 (오페라에 대한 처리는 차후에.. 뭔가 이상함) + xAddEventListener(contentDocument,'dblclick',editorSearchComponent); + xAddEventListener(document,'dblclick',editorSearchComponent); + xAddEventListener(document,'mouseup',editorEventCheck); + xAddEventListener(document,'mousedown',editorHideObject); + + // IE일 경우 ctrl-Enter 안내 문구를 노출 + if(xIE4Up && xGetElementById('for_ie_help_'+editor_sequence)) { + xGetElementById('for_ie_help_'+editor_sequence).style.display = "block"; + } + + /** + * 에디터의 내용을 지속적으로 fo_obj.content의 값과 동기화를 시킴. + * 차후 다른 에디터를 사용하더라도 fo_obj.content와 동기화만 된다면 어떤 에디터라도 사용 가능하도록 하기 위해 + * 별도의 동기화 루틴을 이용함 + **/ + editorSyncContent(editor_rel_keys[editor_sequence]['content'], editor_sequence); + + // 자동저장 필드가 있다면 자동 저장 기능 활성화 + if(typeof(fo_obj._saved_doc_title)!="undefined" ) editorEnableAutoSave(fo_obj, editor_sequence); + + // 크기 변경 불가일 경우 드래그바 숨김 + if(resizable == false) xGetElementById("editor_drag_bar_"+editor_sequence).style.display = "none"; + else xGetElementById("editor_drag_bar_"+editor_sequence).style.display = "block"; + + // editor_mode를 기본으로 설정 + editor_mode[editor_sequence] = null; +} + + + +/** + * 에디터와 form문의 동기화를 위한 함수들 + **/ +// 여러개의 편집기를 예상하여 전역 배열 변수에 form, iframe의 정보를 넣음 +function editorSyncContent(obj, editor_sequence) { + _editorSyncList[_editorSyncList.length] = {field:obj, editor_sequence:editor_sequence} +} + +// 편집기와 폼의 정보를 주기적으로 동기화 시킴 +function _editorSync() { + // 등록된 모든 에디터에 대해 동기화를 시킴 + for(var i=0;i<_editorSyncList.length;i++) { + var field = _editorSyncList[i].field; + var editor_sequence = _editorSyncList[i].editor_sequence; + var content = editorGetContent(editor_sequence); + if(typeof(content)=='undefined') continue; + field.value = content; + } + + // 1.5초마다 계속 동기화 시킴 + setTimeout(_editorSync, 1500); +} + + + +/** + * 자동 저장 기능 + **/ +// 자동 저장 활성화 시키는 함수 (5초마다 자동저장) +function editorEnableAutoSave(fo_obj, editor_sequence) { + var title = fo_obj.title.value; + var content = editor_rel_keys[editor_sequence]['content'].value; + _autoSaveObj = {"fo_obj":fo_obj, "editor_sequence":editor_sequence, "title":title, "content":content, locked:false}; + setTimeout(_editorAutoSave, 5000); +} + +// ajax를 이용하여 editor.procEditorSaveDoc 호출하여 자동 저장시킴 +function _editorAutoSave() { + var fo_obj = _autoSaveObj.fo_obj; + var editor_sequence = _autoSaveObj.editor_sequence; + + // 현재 자동저장중이면 중지 + if(_autoSaveObj.locked == true) return; + + // 대상이 없으면 자동저장 시키는 기능 자체를 중지 + if(!fo_obj || typeof(fo_obj.title)=='undefined' || !editor_sequence) return; + + // 자동저장을 위한 준비 + var title = fo_obj.title.value; + var content = editorGetContent(editor_sequence); + + // 내용이 이전에 저장하였던 것과 다르면 자동 저장을 함 + if(title != _autoSaveObj.title || content != _autoSaveObj.content ) { + var params = new Array(); + + params["title"] = title; + params["content"] = content; + params["document_srl"] = editor_rel_keys[editor_sequence]['primary'].value; + + _autoSaveObj.title = title; + _autoSaveObj.content = content; + + var obj = xGetElementById("editor_autosaved_message_"+editor_sequence); + var oDate = new Date(); + html = oDate.getHours()+':'+oDate.getMinutes()+' '+auto_saved_msg; + xInnerHtml(obj, html); + obj.style.display = "block"; + + // 현재 자동저장중임을 설정 + _autoSaveObj.locked = true; + + // 서버 호출 (서버와 교신중이라는 메세지를 보이지 않도록 함) + show_waiting_message = false; + exec_xml("editor","procEditorSaveDoc", params, function() { _autoSaveObj.locked = false; } ); + show_waiting_message = true; + } + + // 10초마다 동기화를 시킴 + setTimeout(_editorAutoSave, 10000); +} + +// 자동저장된 모든 메세지를 삭제하는 루틴 +function editorRemoveSavedDoc() { + exec_xml("editor","procEditorRemoveSavedDoc"); +} + + +/** + * 에디터의 세부 설정과 데이터 핸들링을 정의한 함수들 + **/ + +// 에디터에 포커스를 줌 +function editorFocus(editor_sequence) { + var iframe_obj = editorGetIFrame(editor_sequence); + iframe_obj.contentWindow.focus(); +} + // 에디터 내의 선택된 부분의 html코드를 변경 function editorReplaceHTML(iframe_obj, html) { iframe_obj.contentWindow.focus(); @@ -259,33 +335,44 @@ function editorReplaceHTML(iframe_obj, html) { } } -// 에디터에 포커스를 줌 -function editorFocus(upload_target_srl) { - var iframe_obj = editorGetIFrame(upload_target_srl); - iframe_obj.contentWindow.focus(); -} +/** + * 키 또는 마우스 이벤트 핸들링 정의 함수 + **/ // 입력 키에 대한 이벤트 체크 function editorKeyPress(evt) { var e = new xEvent(evt); + // 대상을 구함 var obj = e.target; var body_obj = null; if(obj.nodeName == "BODY") body_obj = obj; else body_obj = obj.firstChild.nextSibling; if(!body_obj) return; - var upload_target_srl = body_obj.getAttribute("upload_target_srl"); - if(!upload_target_srl) return; + // editor_sequence는 에디터의 body에 attribute로 정의되어 있음 + var editor_sequence = body_obj.getAttribute("editor_sequence"); + if(!editor_sequence) return; // IE에서 enter키를 눌렀을때 P 태그 대신 BR 태그 입력 - if (xIE4Up && !e.ctrlKey && !e.shiftKey && e.keyCode == 13 && editor_mode[upload_target_srl]!='html') { - var iframe_obj = editorGetIFrame(upload_target_srl); + if (xIE4Up && !e.ctrlKey && !e.shiftKey && e.keyCode == 13 && editor_mode[editor_sequence]!='html') { + var iframe_obj = editorGetIFrame(editor_sequence); if(!iframe_obj) return; + var contentDocument = iframe_obj.contentWindow.document; var obj = contentDocument.selection.createRange(); - obj.pasteHTML('
'); + + var pTag = obj.parentElement().tagName.toLowerCase(); + + switch(pTag) { + case 'li' : + return; + break; + default : + obj.pasteHTML("
\n"); + break; + } obj.select(); evt.cancelBubble = true; evt.returnValue = false; @@ -294,14 +381,21 @@ function editorKeyPress(evt) { // ctrl-S, alt-S 클릭시 submit하기 if( e.keyCode == 115 && (e.altKey || e.ctrlKey) ) { - var iframe_obj = editorGetIFrame(upload_target_srl); + // iframe 에디터를 찾음 + var iframe_obj = editorGetIFrame(editor_sequence); if(!iframe_obj) return; - var contentDocument = iframe_obj.contentWindow.document; - var fo_obj = iframe_obj.parentNode; - while(fo_obj.nodeName != 'FORM') { fo_obj = fo_obj.parentNode; } + // 대상 form을 찾음 + var fo_obj = editorGetForm(editor_sequence); + if(!fo_obj) return; + + // 데이터 동기화 + editor_rel_keys[editor_sequence]['content'].value = editorGetContent(editor_sequence); + + // form문 전송 if(fo_obj.onsubmit) fo_obj.onsubmit(); + // 이벤트 중단 evt.cancelBubble = true; evt.returnValue = false; xPreventDefault(evt); @@ -311,12 +405,12 @@ function editorKeyPress(evt) { // ctrl-b, i, u, s 키에 대한 처리 (파이어폭스에서도 에디터 상태에서 단축키 쓰도록) if (e.ctrlKey) { - var iframe_obj = editorGetIFrame(upload_target_srl); + // iframe 에디터를 찾음 + var iframe_obj = editorGetIFrame(editor_sequence); if(!iframe_obj) return; - var contentDocument = iframe_obj.contentWindow.document; // html 에디터 모드일 경우 이벤트 취소 시킴 - if(editor_mode[upload_target_srl]=='html') { + if(editor_mode[editor_sequence]=='html') { evt.cancelBubble = true; evt.returnValue = false; xPreventDefault(evt); @@ -384,7 +478,64 @@ function editorKeyPress(evt) { } } -// 에디터 상단의 버튼 클릭시 action 처리 (마우스다운 이벤트 발생시마다 요청이 됨) +// 편집 기능 실행 +function editorDo(command, value, target) { + + var doc = null; + + // target이 object인지 editor_sequence인지에 따라 document를 구함 + if(typeof(target)=="object") { + if(xIE4Up) doc = target.parentElement.document; + else doc = target.parentNode; + } else { + var iframe_obj = editorGetIFrame(target); + doc = iframe_obj.contentWindow.document; + } + + var editor_sequence = doc.body.getAttribute('editor_sequence'); + if(editor_mode[editor_sequence]=='html') return; + + // 포커스 + if(typeof(target)=="object") target.focus(); + else editorFocus(target); + + // 실행 + doc.execCommand(command, false, value); + + // 포커스 + if(typeof(target)=="object") target.focus(); + else editorFocus(target); +} + +// 폰트를 변경 +function editorChangeFontName(obj,srl) { + var value = obj.options[obj.selectedIndex].value; + if(!value) return; + editorDo('FontName',value,srl); + obj.selectedIndex = 0; +} + +function editorChangeFontSize(obj,srl) { + var value = obj.options[obj.selectedIndex].value; + if(!value) return; + editorDo('FontSize',value,srl); + obj.selectedIndex = 0; +} + +function editorChangeHeader(obj,srl) { + var value = obj.options[obj.selectedIndex].value; + if(!value) return; + value = "<"+value+">"; + editorDo('formatblock',value,srl); + obj.selectedIndex = 0; +} + + +/** + * 에디터 컴포넌트 구현 부분 + **/ + +// 에디터 상단의 컴포넌트 버튼 클릭시 action 처리 (마우스다운 이벤트 발생시마다 요청이 됨) var editorPrevObj = null; var editorPrevSrl = null; function editorEventCheck(evt) { @@ -395,14 +546,14 @@ function editorEventCheck(evt) { var target_id = e.target.id; if(!target_id) return; - // upload_target_srl와 component name을 구함 (id가 포맷과 다르면 return) + // editor_sequence와 component name을 구함 (id가 포맷과 다르면 return) var info = target_id.split('_'); if(info[0]!="component") return; - var upload_target_srl = info[1]; + var editor_sequence = info[1]; var component_name = target_id.replace(/^component_([0-9]+)_/,''); - if(!upload_target_srl || !component_name) return; + if(!editor_sequence || !component_name) return; - if(editor_mode[upload_target_srl]=='html') return; + if(editor_mode[editor_sequence]=='html') return; switch(component_name) { @@ -413,19 +564,25 @@ function editorEventCheck(evt) { case 'StrikeThrough' : case 'undo' : case 'redo' : - case 'justifyleft' : - case 'justifycenter' : - case 'justifyright' : - case 'indent' : - case 'outdent' : - case 'insertorderedlist' : - case 'insertunorderedlist' : - editorDo(component_name, '', upload_target_srl); + case 'JustifyLeft' : + case 'JustifyCenter' : + case 'JustifyRight' : + case 'JustifyFull' : + case 'Indent' : + case 'Outdent' : + case 'InsertOrderedList' : + case 'InsertUnorderedList' : + case 'SaveAs' : + case 'Copy' : + case 'Cut' : + case 'Paste' : + case 'RemoveFormat' : + editorDo(component_name, '', editor_sequence); break; // 추가 컴포넌트의 경우 서버에 요청을 시도 default : - openComponent(component_name, upload_target_srl); + openComponent(component_name, editor_sequence); break; } @@ -433,11 +590,11 @@ function editorEventCheck(evt) { } // 컴포넌트 팝업 열기 -function openComponent(component_name, upload_target_srl, manual_url) { - editorPrevSrl = upload_target_srl; - if(editor_mode[upload_target_srl]=='html') return; +function openComponent(component_name, editor_sequence, manual_url) { + editorPrevSrl = editor_sequence; + if(editor_mode[editor_sequence]=='html') return; - var popup_url = request_uri+"?module=editor&act=dispEditorPopup&upload_target_srl="+upload_target_srl+"&component="+component_name; + var popup_url = request_uri+"?module=editor&act=dispEditorPopup&editor_sequence="+editor_sequence+"&component="+component_name; if(typeof(manual_url)!="undefined" && manual_url) popup_url += "&manual_url="+escape(manual_url); popopen(popup_url, 'editorComponent'); @@ -453,21 +610,21 @@ function editorSearchComponent(evt) { // 위젯인지 일단 체크 if(obj.getAttribute("widget")) { - // upload_target_srl을 찾음 + // editor_sequence을 찾음 var tobj = obj; while(tobj && tobj.nodeName != "BODY") { tobj = xParent(tobj); } - if(!tobj || tobj.nodeName != "BODY" || !tobj.getAttribute("upload_target_srl")) { + if(!tobj || tobj.nodeName != "BODY" || !tobj.getAttribute("editor_sequence")) { editorPrevNode = null; return; } - var upload_target_srl = tobj.getAttribute("upload_target_srl"); + var editor_sequence = tobj.getAttribute("editor_sequence"); var widget = obj.getAttribute("widget"); editorPrevNode = obj; - if(editor_mode[upload_target_srl]=='html') return; - popopen(request_uri+"?module=widget&act=dispWidgetGenerateCodeInPage&selected_widget="+widget+"&module_srl="+upload_target_srl,'GenerateCodeInPage'); + if(editor_mode[editor_sequence]=='html') return; + popopen(request_uri+"?module=widget&act=dispWidgetGenerateCodeInPage&selected_widget="+widget+"&module_srl="+editor_sequence,'GenerateCodeInPage'); return; } @@ -510,19 +667,19 @@ function editorSearchComponent(evt) { return; } - // upload_target_srl을 찾음 + // editor_sequence을 찾음 var tobj = obj; while(tobj && tobj.nodeName != "BODY") { tobj = xParent(tobj); } - if(!tobj || tobj.nodeName != "BODY" || !tobj.getAttribute("upload_target_srl")) { + if(!tobj || tobj.nodeName != "BODY" || !tobj.getAttribute("editor_sequence")) { editorPrevNode = null; return; } - var upload_target_srl = tobj.getAttribute("upload_target_srl"); + var editor_sequence = tobj.getAttribute("editor_sequence"); // 해당 컴포넌트를 찾아서 실행 - openComponent(editor_component, upload_target_srl); + openComponent(editor_component, editor_sequence); } // 마우스 클릭시 이전 object정보를 숨김 @@ -541,14 +698,15 @@ function editorHideObject(evt) { return; } + /** - * HTML 편집 기능 + * HTML 편집 기능 활성/비활성 **/ -function editorChangeMode(obj, upload_target_srl) { - var iframe_obj = editorGetIFrame(upload_target_srl); +function editorChangeMode(obj, editor_sequence) { + var iframe_obj = editorGetIFrame(editor_sequence); if(!iframe_obj) return; - var textarea_obj = editorGetTextArea(upload_target_srl); + var textarea_obj = editorGetTextArea(editor_sequence); xWidth(textarea_obj, xWidth(iframe_obj.parentNode)); xHeight(textarea_obj, xHeight(iframe_obj.parentNode)); @@ -564,9 +722,9 @@ function editorChangeMode(obj, upload_target_srl) { iframe_obj.parentNode.style.display = "none"; textarea_obj.style.display = "block"; - xGetElementById('xeEditorOption_'+upload_target_srl).style.display = "none"; + xGetElementById('xeEditorOption_'+editor_sequence).style.display = "none"; - editor_mode[upload_target_srl] = 'html'; + editor_mode[editor_sequence] = 'html'; // 위지윅 모드 사용시 } else { @@ -574,68 +732,12 @@ function editorChangeMode(obj, upload_target_srl) { contentDocument.body.innerHTML = html; iframe_obj.parentNode.style.display = "block"; textarea_obj.style.display = "none"; - xGetElementById('xeEditorOption_'+upload_target_srl).style.display = "block"; - editor_mode[upload_target_srl] = null; + xGetElementById('xeEditorOption_'+editor_sequence).style.display = "block"; + editor_mode[editor_sequence] = null; } } -/** - * 편집기능 실행 - */ - -// 편집 기능 실행 -function editorDo(command, value, target) { - - var doc = null; - - // target이 object인지 upload_target_srl인지에 따라 document를 구함 - if(typeof(target)=="object") { - if(xIE4Up) doc = target.parentElement.document; - else doc = target.parentNode; - } else { - var iframe_obj = editorGetIFrame(target); - doc = iframe_obj.contentWindow.document; - } - - var upload_target_srl = doc.body.getAttribute('upload_target_srl'); - if(editor_mode[upload_target_srl]=='html') return; - - // 포커스 - if(typeof(target)=="object") target.focus(); - else editorFocus(target); - - // 실행 - doc.execCommand(command, false, value); - - // 포커스 - if(typeof(target)=="object") target.focus(); - else editorFocus(target); -} - -// 폰트를 변경 -function editorChangeFontName(obj,srl) { - var value = obj.options[obj.selectedIndex].value; - if(!value) return; - editorDo('FontName',value,srl); - obj.selectedIndex = 0; -} - -function editorChangeFontSize(obj,srl) { - var value = obj.options[obj.selectedIndex].value; - if(!value) return; - editorDo('FontSize',value,srl); - obj.selectedIndex = 0; -} - -function editorChangeHeader(obj,srl) { - var value = obj.options[obj.selectedIndex].value; - if(!value) return; - value = "<"+value+">"; - editorDo('formatblock',value,srl); - obj.selectedIndex = 0; -} - /** * iframe 세로 크기 조절 드래그 관련 **/ @@ -708,8 +810,8 @@ function eOptionClick(obj) { } // Editor Info Close -function closeEditorInfo(upload_target_srl) { - xGetElementById('editorInfo_'+upload_target_srl).style.display='none'; +function closeEditorInfo(editor_sequence) { + xGetElementById('editorInfo_'+editor_sequence).style.display='none'; var expire = new Date(); expire.setTime(expire.getTime()+ (7000 * 24 * 3600000)); xSetCookie('EditorInfo', '1', expire); diff --git a/modules/editor/tpl/js/uploader.js b/modules/editor/tpl/js/uploader.js index 690628c9b..bfcfedf51 100755 --- a/modules/editor/tpl/js/uploader.js +++ b/modules/editor/tpl/js/uploader.js @@ -3,51 +3,40 @@ * @version 0.1 * @brief 파일 업로드 관련 * - *********************************************************************************************************************************************** + ***************************************************************************************************************************** * 제로보드XE의 게시물 파일업로드 컴포넌트는 "mmSWFUpload 1.0: Flash upload dialog - http://swfupload.mammon.se/" 를 사용합니다. * - SWFUpload is (c) 2006 Lars Huring and Mammon Media and is released under the MIT License:http://www.opensource.org/licenses/mit-license.php - *********************************************************************************************************************************************** + ***************************************************************************************************************************** + * 감사합니다. **/ var uploading_file = false; var uploaded_files = new Array(); -// 업로드를 하기 위한 준비 시작 -function editor_upload_init(upload_target_srl) { - xAddEventListener(window,'load',function() {editor_upload_form_set(upload_target_srl);} ); +/** + * 업로드를 하기 위한 준비 시작 + * 이 함수는 editor.html 에서 파일 업로드 가능할 경우 호출됨 + **/ +// window.load 이벤트일 경우 && 문서 번호가 가상의 번호가 아니면 기존에 저장되어 있을지도 모르는 파일 목록을 가져옴 +function editor_upload_init(editor_sequence) { + xAddEventListener(window,'load',function() { editor_upload_start(editor_sequence);} ); } -// upload_target_srl에 해당하는 form의 action을 iframe으로 변경 -function editor_upload_form_set(upload_target_srl) { - try { - document.execCommand('BackgroundImageCache',false,true); - } catch(e) { } +function editor_upload_get_target_srl(editor_sequence) { + return editor_rel_keys[editor_sequence]["primary"].value; +} - // SWFUploader load - var uploader_name = "swf_uploader_"+upload_target_srl; - var embed_html = ""; - var flashVars = 'uploadProgressCallback=editor_upload_progress&uploadFileErrorCallback=editor_upload_error_handle&allowedFiletypesDescription='+uploader_setting["allowed_filetypes_description"]+'&autoUpload=true&allowedFiletypes='+uploader_setting["allowed_filetypes"]+'&maximumFilesize='+uploader_setting["allowed_filesize"]+'&uploadQueueCompleteCallback=editor_display_uploaded_file&uploadScript='+escape(request_uri+'?mid='+current_url.getQuery('mid')+'&act=procFileUpload&upload_target_srl='+upload_target_srl+'&PHPSESSID='+xGetCookie(zbxe_session_name)); +function editor_upload_get_uploader_name(editor_sequence) { + return "swf_uploader_"+editor_sequence; - if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length) { - embed_html = ''; - } else { - embed_html = ''; - } +} - if(xIE4Up) { - window.document.body.insertAdjacentHTML("afterEnd", "
"+embed_html+"
"); - } else { - var dummy = xCreateElement("div"); - dummy.style.width = "1px"; - dummy.style.height = "1px"; - dummy.style.position="absolute"; - dummy.style.top="0px"; - dummy.style.left="0px"; - xInnerHtml(dummy, embed_html); - window.document.body.appendChild(dummy); - } +// 파일 업로드를 위한 기본 준비를 함 +function editor_upload_start(editor_sequence) { + // 캐시 삭제 + try { document.execCommand('BackgroundImageCache',false,true); } catch(e) { } - // 임시 iframe을 생성 + // 임시 iframe을 생성 (공통으로 사용) if(!xGetElementById('tmp_upload_iframe')) { if(xIE4Up) { window.document.body.insertAdjacentHTML("afterEnd", ""); @@ -64,41 +53,54 @@ function editor_upload_form_set(upload_target_srl) { } } - // form의 action 을 변경 - var field_obj = xGetElementById("uploaded_file_list_"+upload_target_srl); + // 첨부파일 목록을 출력하는 select element 구함 + var field_obj = xGetElementById("uploaded_file_list_"+editor_sequence); if(!field_obj) return; - var fo_obj = field_obj.parentNode; - while(fo_obj.nodeName != 'FORM') { fo_obj = fo_obj.parentNode; } + // 에디터를 감싸는 form을 구해 submit target을 임시 iframe으로 변경 + var fo_obj = editorGetForm(editor_sequence); fo_obj.target = 'tmp_upload_iframe'; - // upload_target_srl에 해당하는 첨부파일 목록을 로드 (procDeleteFile에 file_srl을 보내주지 않으면 삭제시도는 없이 목록만 갱신할 수 있음) - var module = ""; - if(fo_obj["module"]) module = fo_obj.module.value; - var mid = ""; - if(fo_obj["mid"]) mid = fo_obj.mid.value; - var document_srl = ""; - if(fo_obj["document_srl"]) document_srl = fo_obj.document_srl.value; + // SWF uploader 생성 + var uploader_name = editor_upload_get_uploader_name(editor_sequence); + var embed_html = ""; - // 기 등록된 파일 표시 - editor_display_uploaded_file(upload_target_srl); -} + // 업로드와 관련된 변수 설정 (이 변수들이 그대로 zbxe에 전달됨) + var flashVars = ''+ + 'uploadProgressCallback=editor_upload_progress'+ + '&uploadFileErrorCallback=editor_upload_error_handle'+ + '&allowedFiletypesDescription='+uploader_setting["allowed_filetypes_description"]+ + '&autoUpload=true&allowedFiletypes='+uploader_setting["allowed_filetypes"]+ + '&maximumFilesize='+uploader_setting["allowed_filesize"]+ + '&uploadQueueCompleteCallback=editor_display_uploaded_file'+ + '&uploadScript='+escape( request_uri+'?mid='+current_url.getQuery('mid')+ + '&act=procFileUpload'+ + '&editor_sequence='+editor_sequence+ + '&PHPSESSID='+xGetCookie(zbxe_session_name) + ); -// upload_target_srl에 등록된 파일 표시 -var _prev_upload_target_srl = 0; -function editor_display_uploaded_file(upload_target_srl) { - if(typeof(upload_target_srl)=='undefined'||!upload_target_srl) { - if(_prev_upload_target_srl) { - upload_target_srl = _prev_upload_target_srl; - _prev_upload_target_srl = 0; - } else return; + // 객체 생성 코드 + if(navigator.plugins&&navigator.mimeTypes&&navigator.mimeTypes.length) { + embed_html = ''; + } else { + embed_html = ''; } - var url = request_uri + "?act=procFileDelete&upload_target_srl="+upload_target_srl+"&mid="+current_url.getQuery('mid'); - // iframe에 url을 보내버림 - var iframe_obj = xGetElementById('tmp_upload_iframe'); - if(!iframe_obj) return; - iframe_obj.contentWindow.document.location.href=url; + // div dummy 객체를 만들고 SWFUploader 코드를 추가하여 객체 생성 + var dummy = xCreateElement("div"); + dummy.style.width = "1px"; + dummy.style.height = "1px"; + dummy.style.position="absolute"; + dummy.style.top="0px"; + dummy.style.left="0px"; + window.document.body.appendChild(dummy); + xInnerHtml(dummy, embed_html); + + /** + * upload_target_srl값이 실제 문서 번호일 경우 이미 등록되 있을지도 모르는 첨부파일 목록을 로드 + * procDeleteFile에 file_srl을 보내주지 않으면 삭제시도는 없이 목록만 갱신할 수 있음 + **/ + editor_display_uploaded_file(editor_sequence); } // 파일 업로드 에러 핸들링 @@ -122,18 +124,29 @@ function editor_upload_error_handle(errcode,file,msg) { } } +/** + * 파일 업로드 관련 함수들 + **/ + // 파일 업로드 -function editor_upload_file(upload_target_srl) { - var swf_uploader = xGetElementById("swf_uploader_"+upload_target_srl); - if(!swf_uploader) return; - swf_uploader.browse(); - _prev_upload_target_srl = upload_target_srl; +var _prev_editor_sequence; ///< 진행 상태를 표시하기 위해 바로 이전의 에디터 sequence값을 가지고 있음 +function editor_upload_file(editor_sequence) { + // 업로더 객체를 구함 + var uploader_name = editor_upload_get_uploader_name(editor_sequence); + var swf_uploader = xGetElementById(uploader_name); + + try { + swf_uploader.browse(); + _prev_editor_sequence = editor_sequence; + } catch(e) { + } + } // 업로드 진행상태 표시 var _progress_start = false; function editor_upload_progress(file, bytesLoaded) { - var obj = xGetElementById('uploaded_file_list_'+_prev_upload_target_srl); + var obj = xGetElementById('uploaded_file_list_'+_prev_editor_sequence); if(!_progress_start) { while(obj.options.length) { obj.remove(0); @@ -143,7 +156,7 @@ function editor_upload_progress(file, bytesLoaded) { var percent = Math.ceil((bytesLoaded / file.size) * 100); var filename = file.name; - if(filename.length>15) filename = filename.substr(0,15)+'...'; + if(filename.length>20) filename = filename.substr(0,20)+'...'; var text = filename + ' ('+percent+'%)'; if(!obj.options.length || obj.options[obj.options.length-1].value != file.id) { @@ -154,34 +167,51 @@ function editor_upload_progress(file, bytesLoaded) { } } -// 업로드된 파일 목록 비움 -function editor_upload_clear_list(upload_target_srl) { - var obj = xGetElementById('uploaded_file_list_'+upload_target_srl); +// upload_target_srl 에 등록된 파일 표시 +function editor_display_uploaded_file(editor_sequence) { + if(typeof(editor_sequence)=='undefined'||!editor_sequence) editor_sequence = _prev_editor_sequence; + if(!editor_sequence) return; + + // 이미 등록된 전체 파일 목록을 구해옴 + var url = request_uri + "?act=procFileDelete&editor_sequence="+editor_sequence+"&mid="+current_url.getQuery('mid'); + + // iframe에 url을 보내버림 + var iframe_obj = xGetElementById('tmp_upload_iframe'); + if(!iframe_obj) return; + iframe_obj.contentWindow.document.location.href=url; +} + + +// 업로드된 파일 목록 비움 (단순히 select 객체의 내용을 지우고 미리보기를 제거함) +function editor_upload_clear_list(editor_sequence, upload_target_srl) { + if(!upload_target_srl || upload_target_srl<1) return; + editor_rel_keys[editor_sequence]["primary"].value = upload_target_srl; + + var obj = xGetElementById('uploaded_file_list_'+editor_sequence); while(obj.options.length) { obj.remove(0); } - var preview_obj = xGetElementById('preview_uploaded_'+upload_target_srl); + var preview_obj = xGetElementById('preview_uploaded_'+editor_sequence); xInnerHtml(preview_obj,'') } -// 업로드된 파일 정보를 목록에 추가 -function editor_insert_uploaded_file(upload_target_srl, file_srl, filename, file_size, disp_file_size, uploaded_filename, sid) { - var obj = xGetElementById('uploaded_file_list_'+upload_target_srl); - if(filename.length>15) filename = filename.substr(0,15)+'...'; - var text = filename+' ('+disp_file_size+')'; +// 업로드된 파일 정보를 select 목록에 추가 +function editor_insert_uploaded_file(editor_sequence, file_srl, filename, file_size, disp_file_size, uploaded_filename, sid) { + var obj = xGetElementById('uploaded_file_list_'+editor_sequence); + var text = disp_file_size+' - '+filename; var opt_obj = new Option(text, file_srl, true, true); obj.options[obj.options.length] = opt_obj; var file_obj = {file_srl:file_srl, filename:filename, file_size:file_size, uploaded_filename:uploaded_filename, sid:sid} uploaded_files[file_srl] = file_obj; - editor_preview(obj, upload_target_srl); + editor_preview(obj, editor_sequence); _progress_start = false; } // 파일 목록창에서 클릭 되었을 경우 미리 보기 -function editor_preview(sel_obj, upload_target_srl) { - var preview_obj = xGetElementById('preview_uploaded_'+upload_target_srl); +function editor_preview(sel_obj, editor_sequence) { + var preview_obj = xGetElementById('preview_uploaded_'+editor_sequence); if(!sel_obj.options.length) { xInnerHtml(preview_obj, ''); return; @@ -220,8 +250,8 @@ function editor_preview(sel_obj, upload_target_srl) { } // 업로드된 파일 삭제 -function editor_remove_file(upload_target_srl) { - var obj = xGetElementById('uploaded_file_list_'+upload_target_srl); +function editor_remove_file(editor_sequence) { + var obj = xGetElementById('uploaded_file_list_'+editor_sequence); if(obj.options.length<1) return; // 삭제하려는 파일의 정보를 챙김;; @@ -233,6 +263,10 @@ function editor_remove_file(upload_target_srl) { var iframe_obj = xGetElementById('tmp_upload_iframe'); if(!iframe_obj) return; + // upload_target_srl이 가상 번호일 경우 아무 동작 하지 않음 + var upload_target_srl = editor_rel_keys[editor_sequence]["primary"].value; + if(upload_target_srl<1) return; + for(var i=0;imodule_srl; // 업로드 권한이 없거나 정보가 없을시 종료 - if(!$_SESSION['upload_enable'][$upload_target_srl]) exit(); + if(!$_SESSION['upload_info'][$editor_sequence]->enabled) exit(); + + // upload_target_srl 구함 + $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl; + if(!$upload_target_srl) { + $upload_target_srl = getNextSequence(); + $this->setUploadInfo($editor_sequence, $upload_target_srl); + } $file_info = Context::get('Filedata'); @@ -38,23 +46,27 @@ **/ function procFileDelete() { // 기본적으로 필요한 변수인 upload_target_srl, module_srl을 설정 - $upload_target_srl = Context::get('upload_target_srl'); + $editor_sequence = Context::get('editor_sequence'); $file_srl = Context::get('file_srl'); // 업로드 권한이 없거나 정보가 없을시 종료 - if(!$_SESSION['upload_enable'][$upload_target_srl]) exit(); + if(!$_SESSION['upload_info'][$editor_sequence]->enabled) exit(); + + $upload_target_srl = $_SESSION['upload_info'][$editor_sequence]->upload_target_srl; + if(!$upload_target_srl) return; if($file_srl) $output = $this->deleteFile($file_srl); // 첨부파일의 목록을 java script로 출력 - $this->printUploadedFileList($upload_target_srl); + $this->printUploadedFileList($editor_sequence, $upload_target_srl); } /** * @brief 업로드 가능하다고 세팅 **/ - function setUploadEnable($upload_target_srl) { - $_SESSION['upload_enable'][$upload_target_srl] = true; + function setUploadInfo($editor_sequence, $upload_target_srl=0) { + $_SESSION['upload_info'][$editor_sequence]->enabled = true; + $_SESSION['upload_info'][$editor_sequence]->upload_target_srl = $upload_target_srl; } /** @@ -118,6 +130,7 @@ $output->add('file_srl', $args->file_srl); $output->add('file_size', $args->file_size); $output->add('source_filename', $args->source_filename); + $output->add('upload_target_srl', $upload_target_srl); return $output; } @@ -134,6 +147,8 @@ * @brief 첨부파일 삭제 **/ function deleteFile($file_srl) { + if(!$file_srl) return; + // 파일 정보를 가져옴 $args->file_srl = $file_srl; $output = executeQuery('file.getFile', $args); @@ -149,7 +164,7 @@ if(!$output->toBool()) return $output; // 삭제 성공하면 파일 삭제 - unlink($uploaded_filename); + @unlink($uploaded_filename); return $output; } @@ -211,6 +226,9 @@ $new_file = $path.md5(crypt(rand(1000000,900000), rand(0,100))); } + // 이전 대상이 동일하면 그냥 패스 + if($old_file == $new_file) continue; + // 디렉토리 생성 FileHandler::makeDir($path); @@ -230,7 +248,7 @@ /** * @brief upload_target_srl을 키로 하는 첨부파일을 찾아서 java script 코드로 return **/ - function printUploadedFileList($upload_target_srl) { + function printUploadedFileList($editor_sequence, $upload_target_srl) { // file의 Model객체 생성 $oFileModel = &getModel('file'); @@ -238,17 +256,6 @@ $tmp_file_list = $oFileModel->getFiles($upload_target_srl); $file_count = count($tmp_file_list); - $logged_info = Context::get('logged_info'); - if($logged_info->is_admin == 'Y') { - //$file_config->allowed_filesize = 1024; - //$file_config->allowed_attach_size = 1024; - $file_config->allowed_filesize = ini_get('upload_max_filesize'); - $file_config->allowed_attach_size = ini_get('upload_max_filesize'); - $file_config->allowed_filetypes = '*.*'; - } else { - $file_config = $oFileModel->getFileConfig(); - } - // 루프를 돌면서 $buff 변수에 java script 코드를 생성 $buff = ""; for($i=0;$i<$file_count;$i++) { @@ -260,21 +267,14 @@ } // 업로드 상태 표시 작성 - $upload_status = sprintf( - '%s : %s/ %s
%s : %s (%s : %s)', - Context::getLang('allowed_attach_size'), - FileHandler::filesize($attached_size), - FileHandler::filesize($file_config->allowed_attach_size*1024*1024), - Context::getLang('allowed_filesize'), - FileHandler::filesize($file_config->allowed_filesize*1024*1024), - Context::getLang('allowed_filetypes'), - $file_config->allowed_filetypes - ); + $upload_status = $oFileModel->getUploadStatus($attached_size); + // 필요한 정보들 세팅 Context::set('upload_target_srl', $upload_target_srl); Context::set('file_list', $file_list); Context::set('upload_status', $upload_status); + // 업로드 현황을 브라우저로 알리기 위한 javascript 코드 출력하는 템플릿 호출 $this->setTemplatePath($this->module_path.'tpl'); $this->setTemplateFile('print_uploaded_file_list'); } diff --git a/modules/file/file.model.php b/modules/file/file.model.php index 4aa6a62b3..f66127d2c 100644 --- a/modules/file/file.model.php +++ b/modules/file/file.model.php @@ -79,5 +79,42 @@ return $file_list; } + + /** + * @brief 첨부파일에 대한 설정을 return (관리자/비관리자 자동 구분) + **/ + function getUploadConfig() { + $logged_info = Context::get('logged_info'); + if($logged_info->is_admin == 'Y') { + //$file_config->allowed_filesize = 1024; + //$file_config->allowed_attach_size = 1024; + $file_config->allowed_filesize = ini_get('upload_max_filesize'); + $file_config->allowed_attach_size = ini_get('upload_max_filesize'); + $file_config->allowed_filetypes = '*.*'; + } else { + $file_config = $this->getFileConfig(); + } + return $file_config; + } + + /** + * @brief 파일 업로드를 위한 관리자/비관리자에 따른 안내문구 return + **/ + function getUploadStatus($attached_size = 0) { + $file_config = $this->getUploadConfig(); + + // 업로드 상태 표시 작성 + $upload_status = sprintf( + '%s : %s/ %s
%s : %s (%s : %s)', + Context::getLang('allowed_attach_size'), + FileHandler::filesize($attached_size), + FileHandler::filesize($file_config->allowed_attach_size*1024*1024), + Context::getLang('allowed_filesize'), + FileHandler::filesize($file_config->allowed_filesize*1024*1024), + Context::getLang('allowed_filetypes'), + $file_config->allowed_filetypes + ); + return $upload_status; + } } ?> diff --git a/modules/file/tpl/print_uploaded_file_list.html b/modules/file/tpl/print_uploaded_file_list.html index 1753af723..28051472e 100644 --- a/modules/file/tpl/print_uploaded_file_list.html +++ b/modules/file/tpl/print_uploaded_file_list.html @@ -1,9 +1,9 @@ diff --git a/modules/guestbook/guestbook.admin.view.php b/modules/guestbook/guestbook.admin.view.php index e39de281b..3b8d899ce 100644 --- a/modules/guestbook/guestbook.admin.view.php +++ b/modules/guestbook/guestbook.admin.view.php @@ -26,6 +26,10 @@ // module info를 구하기 위해 module model 객체 생성 $oModuleModel = &getModel('module'); + // 모듈 카테고리 목록을 구함 + $module_category = $oModuleModel->getModuleCategories(); + Context::set('module_category', $module_category); + // module_srl이 있다면 요청된 모듈의 정보를 미리 구해 놓음 if($module_srl) { $module_info = $oModuleModel->getModuleInfoByModuleSrl($module_srl); diff --git a/modules/guestbook/guestbook.controller.php b/modules/guestbook/guestbook.controller.php index 8e6082d61..a37149788 100644 --- a/modules/guestbook/guestbook.controller.php +++ b/modules/guestbook/guestbook.controller.php @@ -114,7 +114,7 @@ // 성공 메세지 등록 $this->add('mid', Context::get('mid')); - $this->add('page', $output->get('page')); + $this->add('page', Context::get('page')); $this->setMessage('success_deleted'); } diff --git a/modules/guestbook/guestbook.view.php b/modules/guestbook/guestbook.view.php index f89565c4e..10f01f14c 100644 --- a/modules/guestbook/guestbook.view.php +++ b/modules/guestbook/guestbook.view.php @@ -80,6 +80,8 @@ * 이 때 여러가지 옵션을 지정하여 다른 에디터 코드를 받을 수 있다. **/ $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'document_srl'; + $option->content_key_name = 'content'; $option->allow_fileupload = false; ///< 파일 업로드 기능을 제한 $option->enable_autosave = true; ///< 자동 저장 기능을 활성화 $option->enable_default_component = true; ///< 기본 에디터 컴포넌트의 활성화 @@ -157,6 +159,8 @@ // 에디터 모듈의 getEditor를 호출하여 세팅 $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'document_srl'; + $option->content_key_name = 'content'; $option->allow_fileupload = $this->grant->fileupload; $option->enable_autosave = true; $option->enable_default_component = true; diff --git a/modules/guestbook/skins/default/comment.html b/modules/guestbook/skins/default/comment.html index 6e04ffb12..929fb703e 100644 --- a/modules/guestbook/skins/default/comment.html +++ b/modules/guestbook/skins/default/comment.html @@ -36,6 +36,7 @@ + {@ $document_srl = $document->document_srl } diff --git a/modules/guestbook/skins/default/list.html b/modules/guestbook/skins/default/list.html index 627a1910a..9c4e1fb42 100644 --- a/modules/guestbook/skins/default/list.html +++ b/modules/guestbook/skins/default/list.html @@ -18,8 +18,8 @@ diff --git a/modules/guestbook/skins/default/write_form.html b/modules/guestbook/skins/default/write_form.html index 077b81209..704b1a7b8 100644 --- a/modules/guestbook/skins/default/write_form.html +++ b/modules/guestbook/skins/default/write_form.html @@ -62,7 +62,7 @@
- +
diff --git a/modules/member/member.admin.controller.php b/modules/member/member.admin.controller.php index 876a69cbc..bbe9bd74a 100644 --- a/modules/member/member.admin.controller.php +++ b/modules/member/member.admin.controller.php @@ -83,16 +83,15 @@ **/ function procMemberAdminInsertConfig() { // 기본 정보를 받음 - $args = Context::gets('skin','colorset','enable_openid','enable_join','limit_day','redirect_url','content','image_name','image_mark', 'image_name_max_width', 'image_name_max_height','image_mark_max_width','image_mark_max_height'); + $args = Context::gets('skin','colorset','enable_openid','enable_join','limit_day','redirect_url','agreement','image_name','image_mark', 'image_name_max_width', 'image_name_max_height','image_mark_max_width','image_mark_max_height'); if(!$args->skin) $args->skin = "default"; if(!$args->colorset) $args->colorset = "white"; if($args->enable_join!='Y') $args->enable_join = 'N'; if($args->enable_openid!='Y') $args->enable_openid= 'N'; if($args->image_name!='Y') $args->image_name = 'N'; if($args->image_mark!='Y') $args->image_mark = 'N'; + if(!trim(strip_tags($args->agreement))) $args->agreement = null; $args->limit_day = (int)$args->limit_day; - $args->agreement = $args->content; - unset($args->content); // module Controller 객체 생성하여 입력 $oModuleController = &getController('module'); diff --git a/modules/member/member.admin.view.php b/modules/member/member.admin.view.php index b1904b17a..a11f18e88 100644 --- a/modules/member/member.admin.view.php +++ b/modules/member/member.admin.view.php @@ -73,6 +73,8 @@ // 에디터를 받음 $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'temp_srl'; + $option->content_key_name = 'agreement'; $option->allow_fileupload = false; $option->enable_autosave = false; $option->enable_default_component = true; @@ -112,6 +114,8 @@ // 에디터 모듈의 getEditor를 호출하여 서명용으로 세팅 if($this->member_info->member_srl) { $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'member_srl'; + $option->content_key_name = 'signature'; $option->allow_fileupload = false; $option->enable_autosave = false; $option->enable_default_component = true; diff --git a/modules/member/member.view.php b/modules/member/member.view.php index 7b263deae..5ebe1f04f 100644 --- a/modules/member/member.view.php +++ b/modules/member/member.view.php @@ -112,6 +112,8 @@ // 에디터 모듈의 getEditor를 호출하여 서명용으로 세팅 if($member_info->member_srl) { $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'member_srl'; + $option->content_key_name = 'signature'; $option->allow_fileupload = false; $option->enable_autosave = false; $option->enable_default_component = true; @@ -320,6 +322,8 @@ // 에디터 모듈의 getEditor를 호출하여 서명용으로 세팅 $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'receiver_srl'; + $option->content_key_name = 'content'; $option->allow_fileupload = false; $option->enable_autosave = false; $option->enable_default_component = true; diff --git a/modules/member/skins/cozy_simple/filter/modify_info.xml b/modules/member/skins/cozy_simple/filter/modify_info.xml index 3a40aab79..d700e2dd1 100644 --- a/modules/member/skins/cozy_simple/filter/modify_info.xml +++ b/modules/member/skins/cozy_simple/filter/modify_info.xml @@ -14,7 +14,7 @@ - + diff --git a/modules/member/skins/cozy_simple/modify_info.html b/modules/member/skins/cozy_simple/modify_info.html index 8a06eddff..74d52d17e 100644 --- a/modules/member/skins/cozy_simple/modify_info.html +++ b/modules/member/skins/cozy_simple/modify_info.html @@ -15,9 +15,8 @@
image_name=='Y' || $member_config->image_mark=='Y')-->enctype="multipart/form-data"> - - +
diff --git a/modules/member/skins/default/filter/modify_info.xml b/modules/member/skins/default/filter/modify_info.xml index 3a40aab79..d700e2dd1 100644 --- a/modules/member/skins/default/filter/modify_info.xml +++ b/modules/member/skins/default/filter/modify_info.xml @@ -14,7 +14,7 @@ - + diff --git a/modules/member/skins/default/modify_info.html b/modules/member/skins/default/modify_info.html index c76cb8d7a..fb987670e 100644 --- a/modules/member/skins/default/modify_info.html +++ b/modules/member/skins/default/modify_info.html @@ -15,9 +15,8 @@ image_name=='Y' || $member_config->image_mark=='Y')-->enctype="multipart/form-data"> - - +
diff --git a/modules/member/tpl/filter/insert.xml b/modules/member/tpl/filter/insert.xml index 684f0c9cc..886a1786a 100644 --- a/modules/member/tpl/filter/insert.xml +++ b/modules/member/tpl/filter/insert.xml @@ -22,7 +22,7 @@ - + diff --git a/modules/member/tpl/insert_member.html b/modules/member/tpl/insert_member.html index c3fadbec0..7e7432e4b 100644 --- a/modules/member/tpl/insert_member.html +++ b/modules/member/tpl/insert_member.html @@ -4,7 +4,7 @@ - + diff --git a/modules/member/tpl/js/signup_check.js b/modules/member/tpl/js/signup_check.js index ed02bb51c..ca8c38c47 100644 --- a/modules/member/tpl/js/signup_check.js +++ b/modules/member/tpl/js/signup_check.js @@ -47,7 +47,10 @@ function completeMemberCheckValue(ret_obj, response_tags, e) { if(ret_obj['message']=='success') { var dummy_id = 'dummy_check_'+name; var dummy = xGetElementById(dummy_id); - if(dummy) xInnerHtml(dummy,''); + if(dummy) { + xInnerHtml(dummy,''); + dummy.style.display = 'none'; + } return; } @@ -59,17 +62,17 @@ function completeMemberCheckValue(ret_obj, response_tags, e) { dummy.style.display = "none"; dummy.style.clear = 'both'; dummy.style.marginTop = '10px'; - obj.parentNode.insertBefore(dummy, obj.nextChild); + obj.parentNode.insertBefore(dummy, obj.lastChild); } xInnerHtml(dummy, ret_obj['message']); dummy.style.display = "block"; - obj.focus(); + //obj.focus(); // 3초 정도 후에 정리 - setTimeout(function() { removeMemberCheckValueOutput(dummy, obj); }, 3000); + //setTimeout(function() { removeMemberCheckValueOutput(dummy, obj); }, 3000); } // 결과 메세지를 정리하는 함수 diff --git a/modules/member/tpl/member_config.html b/modules/member/tpl/member_config.html index c3f935a6c..9c32888a0 100644 --- a/modules/member/tpl/member_config.html +++ b/modules/member/tpl/member_config.html @@ -3,7 +3,8 @@ - + +
diff --git a/modules/module/module.model.php b/modules/module/module.model.php index 505f67323..0ab87b7ae 100644 --- a/modules/module/module.model.php +++ b/modules/module/module.model.php @@ -546,7 +546,7 @@ $info->admin_index_act = $info->admin_index_act; // 설치 유무 체크 (설치는 DB의 설치만 관리) - if($table_count > $created_table_count) $info->need_install = treu; + if($table_count > $created_table_count) $info->need_install = true; else $info->need_install = false; // 각 모듈의 module.class.php로 upgrade 유무 체크 diff --git a/modules/page/page.admin.view.php b/modules/page/page.admin.view.php index 69e2f161a..ef816214c 100644 --- a/modules/page/page.admin.view.php +++ b/modules/page/page.admin.view.php @@ -166,6 +166,8 @@ // 에디터 모듈의 getEditor를 호출하여 세팅 $oEditorModel = &getModel('editor'); + $option->primary_key_name = 'module_srl'; + $option->content_key_name = 'content'; $option->allow_fileupload = true; $option->enable_autosave = false; $option->enable_default_component = true; diff --git a/modules/poll/poll.controller.php b/modules/poll/poll.controller.php index b58f02ec5..ad8aeebcd 100644 --- a/modules/poll/poll.controller.php +++ b/modules/poll/poll.controller.php @@ -164,6 +164,10 @@ // 응답자 정보를 로그로 남김 $log_args->poll_srl = $poll_srl; + + $logged_info = Context::get('logged_info'); + $member_srl = $logged_info->member_srl?$logged_info->member_srl:0; + $log_args->member_srl = $member_srl; $log_args->ipaddress = $_SERVER['REMOTE_ADDR']; $output = executeQuery('poll.insertPollLog', $log_args); diff --git a/modules/trackback/lang/ko.lang.php b/modules/trackback/lang/ko.lang.php index b735c55aa..531feb986 100644 --- a/modules/trackback/lang/ko.lang.php +++ b/modules/trackback/lang/ko.lang.php @@ -4,7 +4,7 @@ * @author zero * @brief 엮인글(trackback) 모듈의 기본 언어팩 **/ - + $lang->cmd_toggle_checked_trackback = '선택항목 반전'; $lang->cmd_delete_checked_trackback = '선택항목 삭제'; $lang->msg_cart_is_null = '삭제할 글을 선택해주세요'; diff --git a/modules/trackback/tpl/filter/insert_config.xml b/modules/trackback/tpl/filter/insert_config.xml index 5f3aba563..3836134ae 100644 --- a/modules/trackback/tpl/filter/insert_config.xml +++ b/modules/trackback/tpl/filter/insert_config.xml @@ -1,4 +1,4 @@ - + diff --git a/modules/trackback/tpl/js/trackback_admin.js b/modules/trackback/tpl/js/trackback_admin.js new file mode 100644 index 000000000..de3f22c2b --- /dev/null +++ b/modules/trackback/tpl/js/trackback_admin.js @@ -0,0 +1,9 @@ +function doCheckAll(bToggle) { + var fo_obj = xGetElementById('fo_list'); + if(typeof(bToggle) == "undefined") bToggle = false; + for(var i=0;i +

{$lang->trackback} {$lang->cmd_management}

@@ -27,7 +28,7 @@ Total {number_format($total_count)}, Page {number_format($page)}/{number_format($total_page)} - + @@ -37,6 +38,7 @@
{$lang->no}
+ + {$lang->cmd_select_all} + {$lang->cmd_toggle_checked_trackback} +
diff --git a/modules/ttimporter/conf/info.xml b/modules/ttimporter/conf/info.xml new file mode 100644 index 000000000..09ac87fad --- /dev/null +++ b/modules/ttimporter/conf/info.xml @@ -0,0 +1,38 @@ + + + TatterTools 데이터 이전 + TatterTools 数据导入 + TTデータ移転 + Transfer data from TatterTools + Transferir datos desde la Herramienta Tatter + + 제로 + zero + Zero + Zero + Zero + + 태터툴즈의 백업파일을 제로보드XE에 입력을 하는 모듈입니다. + 첨부파일 포함하지 않은 백업파일이 필요합니다. + 첨부파일은 원주소에서 직접 다운로드를 하게 됩니다. + + + 导入TatterTools的备份文件到Zeroboard XE的模块。 + 需要不包含附件的备份文件。 + 附件将在原地址直接下载。 + + + TatterToolsのバックアップファイルをゼロボードXE用にデータの変換を行うモジュールです。添付ファイルを含まないバックアップファイルが必要です。添付ファイルは、元のアドレスからダウンロードします。 + + + Module for inputting TattertTools' backup file to ZeroboardXE. + Backup file without attachment is required. + Attachments will be downloaded from the original address. + + + Módulo para ingresar archivos de respaldo de la Herramienta Tatter de ZeroboardXE. + Se requiere archivo de respaldo sin archivos adjuntos. + Archivos adjuntos serán descargados directamente desde la dirección original. + + + diff --git a/modules/ttimporter/conf/module.xml b/modules/ttimporter/conf/module.xml new file mode 100644 index 000000000..a0047cc78 --- /dev/null +++ b/modules/ttimporter/conf/module.xml @@ -0,0 +1,7 @@ + + + + + + + diff --git a/modules/ttimporter/lang/en.lang.php b/modules/ttimporter/lang/en.lang.php new file mode 100644 index 000000000..b31110e03 --- /dev/null +++ b/modules/ttimporter/lang/en.lang.php @@ -0,0 +1,21 @@ +ttimporter = "Import Tetter Tools data"; + $lang->about_tt_importer = "You can input the Tetter Tools data into the module you want.\n The attached file will be directly downloaded via web, so please be sure to enable the original Tetter Tools blog."; + + $lang->target_module = "Target module"; + $lang->target_file = "Target xml file"; + $lang->target_url = "Blog URL"; + + $lang->cmd_continue = 'Continue'; + + $lang->msg_no_xml_file = 'Could not find the XML file! Please check the URL.'; + $lang->msg_invalid_xml_file = 'Invalid XML file type!'; + $lang->msg_importing = 'No. of importing: %d (if stopped long time, please click the "Continue" button.)'; + $lang->msg_import_finished = 'No. of imported: %d (according to condition, some data may not be imported properly.)'; +?> diff --git a/modules/ttimporter/lang/es.lang.php b/modules/ttimporter/lang/es.lang.php new file mode 100644 index 000000000..c28f6f258 --- /dev/null +++ b/modules/ttimporter/lang/es.lang.php @@ -0,0 +1,21 @@ +ttimporter = "Importar datos de la herramienta Tetter"; + $lang->about_tt_importer = "Usted puede ingresar los datos de la herramienta Tetter dentro del módulo lo que desee.\n El archivo adjunto será directamento descargado vía web, por lo que Usted debe activar el blog original de la herrameienta Tetter."; + + $lang->target_module = "Módulo objetivo"; + $lang->target_file = "Archivo xml objetivo"; + $lang->target_url = "URL del Blog"; + + $lang->cmd_continue = 'Continuar'; + + $lang->msg_no_xml_file = 'No se puede encontrar el archivo XML! Por favor chequee la URL.'; + $lang->msg_invalid_xml_file = 'Tipo de archivo XML inválido!'; + $lang->msg_importing = 'Importando %d datos (si permanece detenido mucho tiempo, por favor presiona el botón "Continuar".)'; + $lang->msg_import_finished = '%d datos importados (dependiendo de la condición, algunos datos pueden no ser importados correctamente.)'; +?> diff --git a/modules/ttimporter/lang/jp.lang.php b/modules/ttimporter/lang/jp.lang.php new file mode 100644 index 000000000..96c389050 --- /dev/null +++ b/modules/ttimporter/lang/jp.lang.php @@ -0,0 +1,21 @@ +ttimporter = "TTデータの移転"; + $lang->about_tt_importer = "TatterTools データを希望するモジュールへデータを変換し、入力を行います。添付ファイルは、元のURLから直接ダウンロードするため、元のTatterTools が作動するようにしておいてください。"; + + $lang->target_module = "対象モジュール"; + $lang->target_file = "対象XMLファイル"; + $lang->target_url = "ブログURL"; + + $lang->cmd_continue = '続ける'; + + $lang->msg_no_xml_file = 'XMLファイルが見つかりません。パスを確認してください。'; + $lang->msg_invalid_xml_file = '正しくないフォーマットのXMLファイルです。'; + $lang->msg_importing = '%d個を変換・入力中です。止まっている場合は「続ける」ボタンをクリックしてください。'; + $lang->msg_import_finished = '%d個のデータを変換し、入力が完了しました。正しく変換入力されていないデータがある場合もあります。'; +?> diff --git a/modules/ttimporter/lang/ko.lang.php b/modules/ttimporter/lang/ko.lang.php new file mode 100644 index 000000000..92eb2b85b --- /dev/null +++ b/modules/ttimporter/lang/ko.lang.php @@ -0,0 +1,21 @@ +ttimporter = "태터툴즈 데이터 이전"; + $lang->about_tt_importer = "태터툴즈 데이터를 원하는 모듈에 입력을 할 수 있습니다.\n첨부파일은 웹으로 직접 다운로드를 받으니 꼭 원래 태터툴즈 블로그를 활성화 시켜 주셔야 합니다."; + + $lang->target_module = "대상 모듈"; + $lang->target_file = "대상 xml파일"; + $lang->target_url = "블로그URL"; + + $lang->cmd_continue = '계속진행'; + + $lang->msg_no_xml_file = 'XML파일을 찾을 수 없습니다. 경로를 다시 확인해주세요'; + $lang->msg_invalid_xml_file = '잘못된 형식의 XML파일입니다'; + $lang->msg_importing = '%d개를 입력중입니다. (계속 멈추어 있으면 "계속진행" 버튼을 클릭해주세요)'; + $lang->msg_import_finished = '%d개의 데이터 입력이 완료되었습니다. 상황에 따라 입력되지 못한 데이터가 있을 수 있습니다.'; +?> diff --git a/modules/ttimporter/lang/zh-CN.lang.php b/modules/ttimporter/lang/zh-CN.lang.php new file mode 100644 index 000000000..a6361511f --- /dev/null +++ b/modules/ttimporter/lang/zh-CN.lang.php @@ -0,0 +1,21 @@ +ttimporter = "TatterTools 数据导入"; + $lang->about_tt_importer = "可以把TatterTools 的数据导入到指定的模块当中。\n因附件要在网站直接下载,所以导入前必须先激活原TatterTools 博客。"; + + $lang->target_module = "对象模块"; + $lang->target_file = "对象xml文件"; + $lang->target_url = "博客URL"; + + $lang->cmd_continue = '继续进行'; + + $lang->msg_no_xml_file = '找不到XML文件。请重新确认路径'; + $lang->msg_invalid_xml_file = '错误的XML文件格式。'; + $lang->msg_importing = '正在输入%d个。(长时间停止响应时请按“继续进行”按钮)'; + $lang->msg_import_finished = '已完成%d个数据导入。根据情况可能会有没有被导入的数据。'; +?> diff --git a/modules/ttimporter/tpl/filter/import_tt.xml b/modules/ttimporter/tpl/filter/import_tt.xml new file mode 100644 index 000000000..cf5182a1c --- /dev/null +++ b/modules/ttimporter/tpl/filter/import_tt.xml @@ -0,0 +1,14 @@ + +
+ + + + + + + + + + + +
diff --git a/modules/ttimporter/tpl/index.html b/modules/ttimporter/tpl/index.html new file mode 100644 index 000000000..bd8b1cc96 --- /dev/null +++ b/modules/ttimporter/tpl/index.html @@ -0,0 +1,46 @@ + + + +

{$lang->ttimporter} {$lang->cmd_management}

+ + +
{nl2br($lang->about_tt_importer)}
+ +
+ + + + + + + + + + + + + + + + + +
{$lang->target_module} + +
{$lang->target_file}
{$lang->target_url}
+ +
+ +
+ + + +
diff --git a/modules/ttimporter/tpl/js/importer_admin.js b/modules/ttimporter/tpl/js/importer_admin.js new file mode 100644 index 000000000..cef481fb6 --- /dev/null +++ b/modules/ttimporter/tpl/js/importer_admin.js @@ -0,0 +1,29 @@ +/** + * @file modules/ttimporter/js/importer_admin.js + * @author zero (zero@nzeo.com) + * @brief importer에서 사용하는 javascript + **/ + +/* Step Complete Import */ +function completeImport(ret_obj) { + var message = ret_obj['message']; + var is_finished = ret_obj['is_finished']; + var position = ret_obj['position']; + + xGetElementById("import_status").style.display = "block"; + + if(is_finished=='Y') { + alert(ret_obj["message"]); + location.href = location.href; + } else { + var fo_obj = xGetElementById('fo_import'); + fo_obj.position.value = position; + xInnerHtml('import_status', message); + procFilter(fo_obj, import_tt); + } +} + +function doManualProcess() { + var fo_obj = xGetElementById('fo_import'); + procFilter(fo_obj, import_tt); +} diff --git a/modules/ttimporter/ttimporter.admin.controller.php b/modules/ttimporter/ttimporter.admin.controller.php new file mode 100644 index 000000000..f5040ce9b --- /dev/null +++ b/modules/ttimporter/ttimporter.admin.controller.php @@ -0,0 +1,264 @@ +module_srl = Context::get('module_srl'); + $xml_file = Context::get('xml_file'); + $this->url = Context::get('url'); + $this->position = (int)Context::get('position'); + if(substr($this->url,-1)!='/') $this->url .= '/'; + + // 파일을 찾을 수 없으면 에러 표시 + if(!file_exists($xml_file)) return new Object(-1,'msg_no_xml_file'); + + $this->oXml = new XmlParser(); + + $oDocumentModel = &getModel('document'); + $tmp_category_list = $oDocumentModel->getCategoryList($this->module_srl); + if(count($tmp_category_list)) { + foreach($tmp_category_list as $key => $val) $this->category_list[$val->title] = $key; + } else { + $this->category_list = array(); + } + + // module_srl이 있으면 module데이터로 판단하여 처리, 아니면 회원정보로.. + $is_finished = $this->importDocument($xml_file); + + if($is_finished) { + $this->add('is_finished', 'Y'); + $this->setMessage( sprintf(Context::getLang('msg_import_finished'), $this->imported_count) ); + } else { + $this->add('position', $this->imported_count); + $this->add('is_finished', 'N'); + $this->setMessage( sprintf(Context::getLang('msg_importing'), $this->imported_count) ); + } + } + + /** + * @brief 게시물정보 import + **/ + function importDocument($xml_file) { + $filesize = filesize($xml_file); + + if($filesize<1) return; + + $this->oDocumentController = &getController('document'); + $this->oFileController = &getController('file'); + $this->oCommentController = &getController('comment'); + $this->oTrackbackController = &getController('trackback'); + + $is_finished = true; + + $fp = @fopen($xml_file, "r"); + if($fp) { + $buff = ''; + while(!feof($fp)) { + $str = fread($fp,1024); + $buff .= $str; + + $buff = preg_replace_callback("!(.*?)<\/category>!is", array($this, '_parseCategoryInfo'), trim($buff)); + $buff = preg_replace_callback("!!is", array($this, '_importDocument'), trim($buff)); + + if($this->position+$this->limit_count <= $this->imported_count) { + $is_finished = false; + break; + } + } + fclose($fp); + } + + return $is_finished; + } + + function _insertAttachment($matches) { + $xml_doc = $this->oXml->parse($matches[0]); + + $filename = $xml_doc->attachment->name->body; + $url = sprintf("%sattach/1/%s", $this->url, $filename); + + $tmp_filename = './files/cache/tmp_uploaded_file'; + if(FileHandler::getRemoteFile($url, $tmp_filename)) { + $file_info['tmp_name'] = $tmp_filename; + $file_info['name'] = $filename; + $this->oFileController->insertFile($file_info, $this->module_srl, $this->document_srl, 0, true); + $this->uploaded_count++; + } + @unlink($tmp_filename); + } + + function _importDocument($matches) { + if($this->position > $this->imported_count) { + $this->imported_count++; + return; + } + + $this->uploaded_count = 0; + + $xml_doc = $this->oXml->parse($matches[0]); + + // 문서 번호와 내용 미리 구해 놓기 + $this->document_srl = $args->document_srl = getNextSequence(); + $args->content = $xml_doc->post->content->body; + + // 첨부파일 미리 등록 + preg_replace_callback("!!is", array($this, '_insertAttachment'), $matches[0]); + + // 컨텐츠의 내용 수정 (이미지 첨부파일 관련) + $args->content = preg_replace("!(\[##\_1)([a-zA-Z]){1}\|([^\|]*)\|([^\|]*)\|([^\]]*)\]!is", sprintf('', $this->module_srl, $args->document_srl), $args->content); + + if($xml_doc->post->comment && !is_array($xml_doc->post->comment)) $xml_doc->post->comment = array($xml_doc->post->comment); + + $logged_info = Context::get('logged_info'); + + // 문서 입력 + $args->module_srl = $this->module_srl; + $args->category_srl = $this->category_list[$xml_doc->post->category->body]; + $args->is_notice = 'N'; + $args->is_secret = 'N'; + $args->title = $xml_doc->post->title->body; + $args->readed_count = 0; + $args->voted_count = 0; + $args->comment_count = count($xml_doc->post->comment); + $args->trackback_count = 0; + $args->uploaded_count = $this->uploaded_count; + $args->password = ''; + $args->nick_name = $logged_info->nick_name; + $args->member_srl = $logged_info->member_srl; + $args->user_id = $logged_info->user_id; + $args->user_name = $logged_info->user_name; + $args->email_address = $logged_info->email_address; + $args->homepage = $logged_info->homepage; + + $tag_list = array(); + $tags = $xml_doc->post->tag; + if($tags && !is_array($tags)) $tags = array($tags); + for($i=0;$ibody; + } + $args->tags = implode(',',$tag_list); + $args->regdate = date("YmdHis", $xml_doc->post->created->body); + $args->ipaddress = ''; + $args->allow_comment = $xml_doc->post->acceptcomment->body?'Y':'N'; + $args->lock_comment = 'N'; + $args->allow_trackback = $xml_doc->post->accepttrackback->body?'Y':'N'; + + $output = $this->oDocumentController->insertDocument($args, true); + + if($output->toBool()) { + + // 코멘트 입력 + $comments = $xml_doc->post->comment; + if(count($comments)) { + foreach($comments as $key => $val) { + unset($comment_args); + $comment_args->document_srl = $args->document_srl; + $comment_args->comment_srl = getNextSequence(); + $comment_args->module_srl = $this->module_srl; + $comment_args->parent_srl = 0; + $comment_args->content = $val->content->body; + $comment_args->password = ''; + $comment_args->nick_name = $val->commenter->name->body; + $comment_args->user_id = ''; + $comment_args->user_name = ''; + $comment_args->member_srl = 0; + $comment_args->email_address = ''; + $comment_args->regdate = date("YmdHis",$val->written->body); + $comment_args->ipaddress = $val->commenter->ip->body; + $this->oCommentController->insertComment($comment_args, true); + + if($val->comment) { + $val = $val->comment; + unset($child_comment_args); + $child_comment_args->document_srl = $args->document_srl; + $child_comment_args->comment_srl = getNextSequence(); + $child_comment_args->module_srl = $this->module_srl; + $child_comment_args->parent_srl = $comment_args->comment_srl; + $child_comment_args->content = $val->content->body; + $child_comment_args->password = ''; + $child_comment_args->nick_name = $val->commenter->name->body; + $child_comment_args->user_id = ''; + $child_comment_args->user_name = ''; + $child_comment_args->member_srl = 0; + $child_comment_args->email_address = ''; + $child_comment_args->regdate = date("YmdHis",$val->written->body); + $child_comment_args->ipaddress = $val->commenter->ip->body; + $this->oCommentController->insertComment($child_comment_args, true); + } + + } + } + + /* + // 트랙백 입력 + $trackbacks = $xml_doc->document->trackbacks->trackback; + if($trackbacks && !is_array($trackbacks)) $trackbacks = array($trackbacks); + if(count($trackbacks)) { + foreach($trackbacks as $key => $val) { + $trackback_args->document_srl = $args->document_srl; + $trackback_args->module_srl = $this->module_srl; + $trackback_args->url = $val->url->body; + $trackback_args->title = $val->title->body; + $trackback_args->blog_name = $val->blog_name->body; + $trackback_args->excerpt = $val->excerpt->body; + $trackback_args->regdate = $val->regdate->body; + $trackback_args->ipaddress = $val->ipaddress->body; + $this->oTrackbackController->insertTrackback($trackback_args, true); + } + } + */ + } + + $this->imported_count ++; + return ''; + } + + /** + * @brief 정보를 읽어서 정보를 구함 + **/ + function _parseCategoryInfo($matches) { + $xml_doc = $this->oXml->parse($matches[0]); + if(!$xml_doc->category->priority) return $matches[0]; + + $title = trim($xml_doc->category->name->body); + if(!$title || $this->category_list[$title]) return; + + $oDocumentController = &getAdminController('document'); + $output = $oDocumentController->insertCategory($this->module_srl, $title); + $this->category_list[$title] = $output->get('category_srl'); + } + } +?> diff --git a/modules/ttimporter/ttimporter.admin.view.php b/modules/ttimporter/ttimporter.admin.view.php new file mode 100644 index 000000000..921196a25 --- /dev/null +++ b/modules/ttimporter/ttimporter.admin.view.php @@ -0,0 +1,32 @@ +getMidList(); + Context::set('module_list', $module_list); + + $this->setTemplatePath($this->module_path.'tpl'); + $this->setTemplateFile('index'); + } + + } +?> diff --git a/modules/ttimporter/ttimporter.class.php b/modules/ttimporter/ttimporter.class.php new file mode 100644 index 000000000..1d099d7dc --- /dev/null +++ b/modules/ttimporter/ttimporter.class.php @@ -0,0 +1,36 @@ +insertActionForward('ttimporter', 'view', 'dispTtimporterAdminContent'); + + return new Object(); + } + + /** + * @brief 설치가 이상이 없는지 체크하는 method + **/ + function checkUpdate() { + return false; + } + + /** + * @brief 업데이트 실행 + **/ + function moduleUpdate() { + return new Object(); + } + + } +?> diff --git a/modules/widget/tpl/js/widget_admin.js b/modules/widget/tpl/js/widget_admin.js index f0a99f223..314a89ea5 100644 --- a/modules/widget/tpl/js/widget_admin.js +++ b/modules/widget/tpl/js/widget_admin.js @@ -23,11 +23,11 @@ function completeGenerateCodeInPage(ret_obj,response_tags,params,fo_obj) { // 부모창에 에디터가 있으면 에디터에 추가 if(opener.editorGetIFrame) { - var iframe_obj = opener.editorGetIFrame(module_srl); + var iframe_obj = opener.editorGetIFrame(1); if(iframe_obj) { - opener.editorFocus(module_srl); + opener.editorFocus(1); opener.editorReplaceHTML(iframe_obj, widget_code); - opener.editorFocus(module_srl); + opener.editorFocus(1); } } window.close(); diff --git a/widgets/login_info/skins/xe_official/css/black.css b/widgets/login_info/skins/xe_official/css/black.css index f1b542774..b4d61ccd9 100644 --- a/widgets/login_info/skins/xe_official/css/black.css +++ b/widgets/login_info/skins/xe_official/css/black.css @@ -3,7 +3,7 @@ #login legend { display:block; width:0; height:0; overflow:hidden; font-size:0;} #login form { position:relative; border:1px solid #6b6b6b; padding:11px 11px 7px 11px; width:172px;} #login form .idpwWrap { overflow:hidden; clear:both; width:172px;} -#login form .idpw { float:left;} +#login form .idpw { float:left; width:110px;} #login form .idpw input { border:1px solid #6b6b6b; color:#cbcbcb; width:105px; background:#515151; padding:1px 5px; margin-bottom:2px; font:.9em Tahoma;} #login form .login { float:right;} #login form p.save { clear:both; padding:.3em 0;} diff --git a/widgets/login_info/skins/xe_official/css/default.css b/widgets/login_info/skins/xe_official/css/default.css index 46e93b6d2..18913b72b 100644 --- a/widgets/login_info/skins/xe_official/css/default.css +++ b/widgets/login_info/skins/xe_official/css/default.css @@ -3,7 +3,7 @@ #login legend { display:block; width:0; height:0; overflow:hidden; font-size:0;} #login form { position:relative; border:1px solid #cacaca; padding:11px 11px 7px 11px; width:172px;} #login form .idpwWrap { overflow:hidden; clear:both; width:172px;} -#login form .idpw { float:left;} +#login form .idpw { float:left; width:110px; } #login form .idpw input { border:1px solid #c9c9c9; color:#282828; width:105px; background:#fbfbfb; padding:1px 5px; margin-bottom:2px; font:.9em Tahoma;} #login form .login { float:right;} #login form p.save { clear:both; padding:.3em 0;} diff --git a/widgets/login_info/skins/xe_official/css/white.css b/widgets/login_info/skins/xe_official/css/white.css index f8dbb1671..fb5c2eea2 100644 --- a/widgets/login_info/skins/xe_official/css/white.css +++ b/widgets/login_info/skins/xe_official/css/white.css @@ -3,7 +3,7 @@ #login legend { display:block; width:0; height:0; overflow:hidden; font-size:0;} #login form { position:relative; border:1px solid #cacaca; padding:11px 11px 7px 11px; width:172px;} #login form .idpwWrap { overflow:hidden; clear:both; width:172px;} -#login form .idpw { float:left;} +#login form .idpw { float:left; width:110px;} #login form .idpw input { border:1px solid #c9c9c9; color:#282828; width:105px; background:#fbfbfb; padding:1px 5px; margin-bottom:2px; font:.9em Tahoma;} #login form .login { float:right;} #login form p.save { clear:both; padding:.3em 0;}