diff --git a/common/js/xml_handler.js b/common/js/xml_handler.js index d5f50efd3..fa8549899 100644 --- a/common/js/xml_handler.js +++ b/common/js/xml_handler.js @@ -55,6 +55,8 @@ function xml_response_filter(oXml, callback_func, response_tags, callback_func_a callback_func(ret_obj, response_tags, callback_func_arg, fo_obj); + oXml.clear(); + return null; } @@ -67,6 +69,7 @@ function xml_handler() { this.params = new Array(); this.reset = xml_handlerReset; + this.clear = xml_handlerClear; this.getXmlHttp = zGetXmlHttp; this.request = xml_handlerRequest; this.setPath = xml_handlerSetPath; @@ -123,6 +126,10 @@ function xml_handlerReset() { this.params = new Array(); } +function xml_handlerClear() { + this.obj_xmlHttp = null; +} + function xml_handlerAddParam(key, val) { this.params[key] = val; } diff --git a/modules/comment/queries/insertComment.xml b/modules/comment/queries/insertComment.xml index c6fd81e3f..fbfb2e8a2 100644 --- a/modules/comment/queries/insertComment.xml +++ b/modules/comment/queries/insertComment.xml @@ -20,6 +20,7 @@ + diff --git a/modules/document/document.item.php b/modules/document/document.item.php index afc3b8396..64545659c 100644 --- a/modules/document/document.item.php +++ b/modules/document/document.item.php @@ -99,7 +99,8 @@ // 전체 설정에서 허용시 모듈별 설정을 체크 else { $module_config = $trackback_config->module_config[$this->get('module_srl')]; - if(!$module_config || $module_config->enable_trackback != 'Y') $this->allow_trackback_status = false; + if(!$module_config || $module_config->enable_trackback != 'N') $this->allow_trackback_status = true; + else $this->allow_trackback_status = false; } } } diff --git a/modules/file/queries/insertFile.xml b/modules/file/queries/insertFile.xml index 9d846a3e3..669cb4f30 100644 --- a/modules/file/queries/insertFile.xml +++ b/modules/file/queries/insertFile.xml @@ -16,5 +16,6 @@ + diff --git a/modules/importer/conf/module.xml b/modules/importer/conf/module.xml index db64b2017..b923bd987 100644 --- a/modules/importer/conf/module.xml +++ b/modules/importer/conf/module.xml @@ -3,6 +3,9 @@ + + + diff --git a/modules/importer/extract.class.php b/modules/importer/extract.class.php new file mode 100644 index 000000000..9d43b75fd --- /dev/null +++ b/modules/importer/extract.class.php @@ -0,0 +1,207 @@ +filename = $filename; + + $this->startTag = $startTag; + if($endTag) $this->endTag = $endTag; + $this->itemStartTag = $itemTag; + $this->itemEndTag = $itemEndTag; + + $this->key = md5($filename); + + $this->cache_path = './files/cache/tmp/'.$this->key; + $this->cache_index_file = $this->cache_path.'/index'; + + if(!is_dir($this->cache_path)) FileHandler::makeDir($this->cache_path); + + return $this->openFile(); + } + + /** + * @brief 지정된 파일의 지시자를 염 + **/ + function openFile() { + @unlink($this->cache_index_file); + $this->index_fd = fopen($this->cache_index_file,"a"); + + // local 파일일 경우 + if(!preg_match('/^http:/i',$this->filename)) { + if(!file_exists($this->filename)) return new Object(-1,'msg_no_xml_file'); + $this->fd = fopen($this->filename,"r"); + + // remote 파일일 경우 + } else { + $url_info = parse_url($this->filename); + if(!$url_info['port']) $url_info['port'] = 80; + if(!$url_info['path']) $url_info['path'] = '/'; + + $this->fd = @fsockopen($url_info['host'], $url_info['port']); + if(!$this->fd) return new Object(-1,'msg_no_xml_file'); + + // 한글 파일이 있으면 한글파일 부분만 urlencode하여 처리 (iconv 필수) + $path = $url_info['path']; + if(preg_match('/[\xEA-\xED][\x80-\xFF]{2}/', $path)&&function_exists('iconv')) { + $path_list = explode('/',$path); + $cnt = count($path_list); + $filename = $path_list[$cnt-1]; + $filename = urlencode(iconv("UTF-8","EUC-KR",$filename)); + $path_list[$cnt-1] = $filename; + $path = implode('/',$path_list); + $url_info['path'] = $path; + } + + $header = sprintf("GET %s?%s HTTP/1.0\r\nHost: %s\r\nReferer: %s://%s\r\nConnection: Close\r\n\r\n", $url_info['path'], $url_info['query'], $url_info['host'], $url_info['scheme'], $url_info['host']); + @fwrite($this->fd, $header); + $buff = ''; + while(!feof($this->fd)) { + $buff .= $str = fgets($this->fd, 1024); + if(!trim($str)) break; + } + if(preg_match('/404 Not Found/i',$buff)) return new Object(-1,'msg_no_xml_file'); + } + + if($this->startTag) { + while(!feof($this->fd)) { + $str = fgets($this->fd, 1024); + $pos = strpos($str, $this->startTag); + if($pos !== false) { + $this->buff = substr($this->buff, $pos+strlen($this->startTag)); + $this->isStarted = true; + $this->isFinished = false; + break; + } + } + } else { + $this->isStarted = true; + $this->isFinished = false; + } + + return new Object(); + } + + function closeFile() { + $this->isFinished = true; + fclose($this->fd); + fclose($this->index_fd); + } + + function isFinished() { + return $this->isFinished || !$this->fd || feof($this->fd); + } + + function saveItems() { + $this->index = 0; + while(!$this->isFinished()) { + $this->getItem(); + } + } + + function mergeItems($filename) { + $this->saveItems(); + + $filename = sprintf('%s/%s', $this->cache_path, $filename); + + $index_fd = fopen($this->cache_index_file,"r"); + $fd = fopen($filename,'w'); + + fwrite($fd, ''); + while(!feof($index_fd)) { + $target_file = trim(fgets($index_fd,1024)); + if(!file_exists($target_file)) continue; + $buff = FileHandler::readFile($target_file); + fwrite($fd, FileHandler::readFile($target_file)); + + @unlink($target_file); + } + fwrite($fd, ''); + fclose($fd); + } + + function getItem() { + if($this->isFinished()) return; + + while(!feof($this->fd)) { + $startPos = strpos($this->buff, $this->itemStartTag); + if($startPos !== false) { + $this->buff = substr($this->buff, $startPos); + break; + } elseif($this->endTag) { + $endPos = strpos($this->buff, $this->endTag); + if($endPos !== false) { + $this->closeFile(); + return; + } + } + $this->buff .= fgets($this->fd, 1024); + } + + $startPos = strpos($this->buff, $this->itemStartTag); + if($startPos === false) { + $this->closeFile(); + return; + } + + $filename = sprintf('%s/%s.xml',$this->cache_path, $this->index++); + fwrite($this->index_fd, $filename."\r\n"); + + $fd = fopen($filename,'w'); + + while(!feof($this->fd)) { + $endPos = strpos($this->buff, $this->itemEndTag); + if($endPos !== false) { + $endPos += strlen($this->itemEndTag); + $buff = substr($this->buff, 0, $endPos); + fwrite($fd, $this->_addTagCRTail($buff)); + fclose($fd); + $this->buff = substr($this->buff, $endPos); + break; + } + + fwrite($fd, $this->_addTagCRTail($this->buff)); + $this->buff = fgets($this->fd, 1024); + } + } + + function getTotalCount() { + return $this->index; + } + + function getKey() { + return $this->key; + } + + function _addTagCRTail($str) { + $str = preg_replace('/<\/([^>]*)>\r\n<", $str); + return $str; + } + } +?> diff --git a/modules/importer/importer.admin.controller.php b/modules/importer/importer.admin.controller.php index 3d1793def..4b4ecbf78 100644 --- a/modules/importer/importer.admin.controller.php +++ b/modules/importer/importer.admin.controller.php @@ -5,18 +5,12 @@ * @brief importer 모듈의 admin controller class **/ + @set_time_limit(0); + @require_once('./modules/importer/extract.class.php'); + class importerAdminController extends importer { - var $oMemberController = null; - var $oMemberModel = null; - var $default_group_srl = 0; - - var $oDocumentController = null; - var $oDocumentModel = null; - var $oCommentController = null; - var $oCommentModel = null; - var $oTrackbackController = null; - + var $unit_count = 300; var $oXmlParser = null; /** @@ -29,8 +23,6 @@ * @brief 회원정보와 게시물 정보를 싱크 **/ function procImporterAdminSync() { - set_time_limit(0); - // 게시물정보 싱크 $output = executeQuery('importer.updateDocumentSync'); @@ -41,25 +33,127 @@ } /** - * @brief 회원xml 파일을 분석해서 import + * @brief XML파일을 미리 분석하여 개발 단위로 캐싱 **/ - function procImporterAdminMemberImport() { - set_time_limit(0); - + function procImporterAdminPreProcessing() { + // 이전할 대상 xml파일을 구함 $xml_file = Context::get('xml_file'); - $total_count = (int)Context::get('total_count'); - $success_count = (int)Context::get('success_count'); - $readed_line = (int)Context::get('readed_line'); - // xml_file 경로가 없으면 에러~ - if(!$xml_file) return new Object(-1, 'msg_no_xml_file'); + // 이전할 대상의 type을 구함 + $type = Context::get('type'); - // local 파일 지정인데 파일이 없으면 역시 에러~ - if(!preg_match('/^http:/i',$xml_file) && (!preg_match("/\.xml$/i", $xml_file) || !file_exists($xml_file)) ) return new Object(-1,'msg_no_xml_file'); + // xml파일에서 정해진 규칙으로 캐싱 + $oExtract = new extract(); - // 이제부터 데이터를 가져오면서 처리 - $fp = $this->getFilePoint($xml_file); - if(!$fp) return new Object(-1,'msg_no_xml_file'); + switch($type) { + case 'member' : + $output = $oExtract->set($xml_file,'', '', ''); + if($output->toBool()) $oExtract->saveItems(); + break; + case 'message' : + $output = $oExtract->set($xml_file,'', '',''); + if($output->toBool()) $oExtract->saveItems(); + break; + case 'ttxml' : + // 카테고리 정보를 먼저 구함 + $output = $oExtract->set($xml_file,'', '',''); + if($output->toBool()) { + $oExtract->mergeItems('category'); + + // 개별 아이템 구함 + $output = $oExtract->set($xml_file,'', ''); + if($output->toBool()) $oExtract->saveItems(); + } + break; + default : + // 카테고리 정보를 먼저 구함 + $output = $oExtract->set($xml_file,'', '', '',''); + if($output->toBool()) { + $oExtract->mergeItems('category'); + + // 개별 아이템 구함 + $output = $oExtract->set($xml_file,'', '', ''); + if($output->toBool()) $oExtract->saveItems(); + } + break; + + } + + if(!$output->toBool()) { + $this->add('error',0); + $this->add('status',-1); + $this->setMessage($output->getMessage()); + return; + } + + // extract가 종료됨을 알림 + $this->add('type',$type); + $this->add('total',$oExtract->getTotalCount()); + $this->add('cur',0); + $this->add('key', $oExtract->getKey()); + $this->add('status',0); + } + + /** + * @brief xml파일의 내용이 extract되고 난후 차례대로 마이그레이션 + **/ + function procImporterAdminImport() { + // 변수 설정 + $type = Context::get('type'); + $total = Context::get('total'); + $cur = Context::get('cur'); + $key = Context::get('key'); + $user_id = Context::get('user_id'); + $target_module = Context::get('target_module'); + $this->unit_count = Context::get('unit_count'); + + // index파일이 있는지 확인 + $index_file = './files/cache/tmp/'.$key.'/index'; + if(!file_exists($index_file)) return new Object(-1, 'msg_invalid_xml_file'); + + switch($type) { + case 'ttxml' : + if(!$target_module) return new Object(-1,'msg_invalid_request'); + + require_once('./modules/importer/ttimport.class.php'); + $oTT = new ttimport(); + $cur = $oTT->importModule($key, $cur, $index_file, $this->unit_count, $target_module, $user_id); + break; + case 'message' : + $cur = $this->importMessage($key, $cur, $index_file); + break; + case 'member' : + $cur = $this->importMember($key, $cur, $index_file); + break; + case 'module' : + // 타켓 모듈의 유무 체크 + if(!$target_module) return new Object(-1,'msg_invalid_request'); + $cur = $this->importModule($key, $cur, $index_file, $target_module); + break; + } + + // extract가 종료됨을 알림 + $this->add('type',$type); + $this->add('total',$total); + $this->add('cur',$cur); + $this->add('key', $key); + $this->add('target_module', $target_module); + + // 모두 입력시 성공 메세지 출력하고 cache 파일제거 + if($total <= $cur) { + $this->setMessage( sprintf(Context::getLang('msg_import_finished'), $cur, $total) ); + FileHandler::removeFilesInDir('./files/cache/tmp/'); + } else $this->setMessage( sprintf(Context::getLang('msg_importing'), $total, $cur) ); + } + + /** + * @brief 회원 정보 입력 + **/ + function importMember($key, $cur, $index_file) { + if(!$cur) $cur = 0; + + // xmlParser객체 생성 + $oXmlParser = new XmlParser(); // 회원 입력을 위한 기본 객체들 생성 $this->oMemberController = &getController('member'); @@ -67,593 +161,674 @@ // 기본 회원 그룹을 구함 $default_group = $this->oMemberModel->getDefaultGroup(); - $this->default_group_srl = $default_group->group_srl; + $default_group_srl = $default_group->group_srl; - $obj = null; - $extra_var = null; - $is_extra_var = false; + // index파일을 염 + $f = fopen($index_file,"r"); - $inserted_count = 0; + // 이미 읽혀진 것은 패스 + for($i=0;$i<$cur;$i++) fgets($f, 1024); - // 본문 데이터부터 처리 시작 - $read_line = 0; - while(!feof($fp)) { - $str = trim(fgets($fp, 1024)); + // 라인단위로 읽어들이면서 $cur보다 커지고 $cur+$this->unit_count개보다 작으면 중지 + for($idx=$cur;$idx<$cur+$this->unit_count;$idx++) { + if(feof($f)) break; - if($str == "") $read_line ++; - if($read_line < $readed_line) continue; + // 정해진 위치를 찾음 + $target_file = trim(fgets($f, 1024)); - // 한 아이템 준비 시작 - if($str == '') { - $obj = $extra_var = null; - $is_extra_var = false; - continue; + // 대상 파일을 읽여서 파싱후 입력 + $xmlObj = $oXmlParser->loadXmlFile($target_file); + @unlink($target_file); + if(!$xmlObj) continue; - // 추가 변수 시자r 일 경우 - } elseif($str == '') { - $is_extra_var = true; + // 객체 정리 + $obj = null; + $obj->user_id = base64_decode($xmlObj->member->user_id->body); + $obj->password = base64_decode($xmlObj->member->password->body); + $obj->user_name = base64_decode($xmlObj->member->user_name->body); + $obj->nick_name = base64_decode($xmlObj->member->nick_name->body); + $obj->email = base64_decode($xmlObj->member->email->body); + $obj->homepage = base64_decode($xmlObj->member->homepage->body); + $obj->blog = base64_decode($xmlObj->member->blog->body); + $obj->birthday = substr(base64_decode($xmlObj->member->birthday->body),0,8); + $obj->allow_mailing = base64_decode($xmlObj->member->allow_mailing->body); + $obj->point = base64_decode($xmlObj->member->point->body); + $obj->image_nickname = base64_decode($xmlObj->member->image_nickname->buff->body); + $obj->image_mark = base64_decode($xmlObj->member->image_mark->buff->body); + $obj->profile_image = base64_decode($xmlObj->member->profile_image->buff->body); + $obj->signature = base64_decode($xmlObj->member->signature->body); + $obj->regdate = base64_decode($xmlObj->member->regdate->body); + $obj->last_login = base64_decode($xmlObj->member->last_login->body); - // 추가 변수 종료 일 경우 - } elseif($str == '') { - $is_extra_var = false; - $obj->extra_vars = $extra_var; - - // 아이템 종료시 DB 입력 - } else if( $str == '') { - if($this->importMember($obj)) $inserted_count ++; - if($inserted_count >= 300) { - $manual_break = true; - break; - } - - // members 태그 체크 (전체 개수를 구함) - } else if(substr($str,0,8)=='') { - break; - - // 이미지 마크, 이미지이름, 프로필 사진일 경우 - } else if(in_array($str, array('','',''))) { - - // binary buffer일 경우 임의의 위치에 파일을 저장시켜 놓고 그 파일의 경로를 return - $key = substr($str,1,strlen($str)-2); - $filename = $this->readFileBuff($fp, $key); - $obj->{$key} = $filename; - - // 변수 체크 - } else { - $buff .= $str; - $pos = strpos($buff, '>'); - $key = substr($buff, 1, $pos-1); - if(substr($buff, -1 * ( strlen($key)+3)) == '') { - $val = base64_decode(substr($buff, $pos, strlen($buff)-$pos*2-2)); - if($is_extra_var) $extra_var->{$key} = $val; - else $obj->{$key} = $val; - $buff = null; + if($xmlObj->member->extra_vars) { + foreach($xmlObj->member->extra_vars as $key => $val) { + if(in_array($key, array('node_name','attrs','body'))) continue; + $obj->extra_vars->{$key} = base64_decode($val->body); } } - } - fclose($fp); + // homepage, blog의 url을 정확히 만듬 + if($obj->homepage && !preg_match("/^http:\/\//i",$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; + if($obj->blog && !preg_match("/^http:\/\//i",$obj->blog)) $obj->blog = 'http://'.$obj->blog; - $success_count += $inserted_count; + // email address 필드 정리 + $obj->email_address = $obj->email; + list($obj->email_id, $obj->email_host) = explode('@', $obj->email); - if($manual_break) { - $this->add('total_count',$total_count); - $this->add('success_count',$success_count); - $this->add('readed_line',$read_line); - $this->add('is_finished','0'); - $this->setMessage(sprintf(Context::getLang('msg_importing'), $total_count, $success_count)); - } else { - $this->add('is_finished','1'); - $this->setMessage(sprintf(Context::getLang('msg_import_finished'), $success_count, $total_count)); - } - } + // 메일링 허용 체크 + if($obj->allow_mailing!='Y') $obj->allow_mailing = 'N'; - /** - * @brief 주어진 xml 파일을 파싱해서 회원 정보 입력 - **/ - function importMember($obj) { - // homepage, blog의 url을 정확히 만듬 - if($obj->homepage && !preg_match("/^http:\/\//i",$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; - if($obj->blog && !preg_match("/^http:\/\//i",$obj->blog)) $obj->blog = 'http://'.$obj->blog; + // 쪽지 수신 체크 + $obj->allow_message = 'Y'; + if(!in_array($obj->allow_message, array('Y','N','F'))) $obj->allow_message= 'Y'; - $obj->email_address = $obj->email; - list($obj->email_id, $obj->email_host) = explode('@', $obj->email); + // 최종 로그인 시간이 없으면 가입일을 입력 + if(!$obj->last_login) $obj->last_login = $obj->regdate; - if($obj->allow_mailing!='Y') $obj->allow_mailing = 'N'; + // 회원 번호를 구함 + $obj->member_srl = getNextSequence(); - $obj->allow_message = 'Y'; - if(!in_array($obj->allow_message, array('Y','N','F'))) $obj->allow_message= 'Y'; + // 확장변수의 정리 + $extra_vars = $obj->extra_vars; + unset($obj->extra_vars); + $obj->extra_vars = serialize($extra_vars); - $obj->member_srl = getNextSequence(); - - $extra_vars = $obj->extra_vars; - unset($obj->extra_vars); - $obj->extra_vars = serialize($extra_vars); - - $output = executeQuery('member.insertMember', $obj); - - // 입력실패시 닉네임 중복인지 확인 - if(!$output->toBool()) { - - // 닉네임 중복이라면 닉네임을 바꾸어서 입력 + // 중복되는 nick_name 데이터가 있는지 체크 + $nick_args = null; $nick_args->nick_name = $obj->nick_name; $nick_output = executeQuery('member.getMemberSrl', $nick_args); - if($nick_output->data->member_srl) { - $obj->nick_name .= rand(111,999); - $output = executeQuery('member.insertMember', $obj); - } - } + if(!$nick_output->toBool()) $obj->nick_name .= '_'.$obj->member_srl; - // 입력 성공시 - if($output->toBool()) { + // 회원 추가 + $output = executeQuery('member.insertMember', $obj); - // 기본 그룹 가입 시킴 - $obj->group_srl = $this->default_group_srl; - executeQuery('member.addMemberToGroup',$obj); + // 입력 성공시 그룹 가입/ 이미지이름-마크-서명등을 추가 + if($output->toBool()) { - // 이미지네임 - if($obj->image_nickname && file_exists($obj->image_nickname)) { - $target_path = sprintf('files/member_extra_info/image_name/%s/', getNumberingPath($obj->member_srl)); - if(!is_dir($target_path)) FileHandler::makeDir($target_path); - $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl); - @rename($obj->image_nickname, $target_filename); - } + // 기본 그룹 가입 시킴 + $obj->group_srl = $default_group_srl; + executeQuery('member.addMemberToGroup',$obj); - // 이미지마크 - if($obj->image_mark && file_exists($obj->image_mark)) { - $target_path = sprintf('files/member_extra_info/image_mark/%s/', getNumberingPath($obj->member_srl)); - if(!is_dir($target_path)) FileHandler::makeDir($target_path); - $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl); - @rename($obj->image_mark, $target_filename); - } - - // 프로필 이미지 - if($obj->profile_image && file_exists($obj->profile_image)) { - $target_path = sprintf('files/member_extra_info/profile_image/%s/', getNumberingPath($obj->member_srl)); - if(!is_dir($target_path)) FileHandler::makeDir($target_path); - $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl); - @rename($obj->profile_image, $target_filename); - } - - // 서명 - if($obj->signature) { - $signature = removeHackTag($obj->signature); - $signature_buff = sprintf('%s', $signature); - - $target_path = sprintf('files/member_extra_info/signature/%s/', getNumberingPath($obj->member_srl)); - if(!is_dir($target_path)) FileHandler::makeDir($target_path); - $target_filename = sprintf('%s%d.signature.php', $target_path, $obj->member_srl); - - FileHandler::writeFile($target_filename, $signature_buff); - } - return true; - } - - return false; - } - - /** - * @brief 메세지xml 파일을 분석해서 import - **/ - function procImporterAdminMessageImport() { - set_time_limit(0); - - $xml_file = Context::get('xml_file'); - $total_count = (int)Context::get('total_count'); - $success_count = (int)Context::get('success_count'); - $readed_line = (int)Context::get('readed_line'); - - // xml_file 경로가 없으면 에러~ - if(!$xml_file) return new Object(-1, 'msg_no_xml_file'); - - // local 파일 지정인데 파일이 없으면 역시 에러~ - if(!preg_match('/^http:/i',$xml_file) && (!preg_match("/\.xml$/i", $xml_file) || !file_exists($xml_file)) ) return new Object(-1,'msg_no_xml_file'); - - // 이제부터 데이터를 가져오면서 처리 - $fp = $this->getFilePoint($xml_file); - if(!$fp) return new Object(-1,'msg_no_xml_file'); - - $obj = null; - $inserted_count = 0; - - // 본문 데이터부터 처리 시작 - $read_line = 0; - while(!feof($fp)) { - $str = trim(fgets($fp, 1024)); - - if($str == "") $read_line ++; - if($read_line < $readed_line) continue; - - // 한 아이템 준비 시작 - if($str == '') { - $obj = null; - continue; - - // 아이템 종료시 DB 입력 - } else if( $str == '') { - if($this->importMessage($obj)) $inserted_count ++; - if($inserted_count >= 100) { - $manual_break = true; - break; + // 이미지네임 + if($obj->image_nickname) { + $target_path = sprintf('files/member_extra_info/image_name/%s/', getNumberingPath($obj->member_srl)); + $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl); + FileHandler::writeFile($target_filename, $obj->image_nickname); } - // messages 태그 체크 (전체 개수를 구함) - } else if(substr($str,0,9)=='image_mark && file_exists($obj->image_mark)) { + $target_path = sprintf('files/member_extra_info/image_mark/%s/', getNumberingPath($obj->member_srl)); + $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl); + FileHandler::writeFile($target_filename, $obj->image_mark); + } - // 선언구 패스~ - } else if(substr($str,0,5)=='') { - break; + // 프로필 이미지 + if($obj->profile_image) { + $target_path = sprintf('files/member_extra_info/profile_image/%s/', getNumberingPath($obj->member_srl)); + $target_filename = sprintf('%s%d.gif', $target_path, $obj->member_srl); + FileHandler::writeFile($target_filename, $obj->profile_image); + } - // 변수 체크 - } else { - $buff .= $str; - $pos = strpos($buff, '>'); - $key = substr($buff, 1, $pos-1); - if(substr($buff, -1 * ( strlen($key)+3)) == '') { - $val = base64_decode(substr($buff, $pos, strlen($buff)-$pos*2-2)); - if($is_extra_var) $extra_var->{$key} = $val; - else $obj->{$key} = $val; - $buff = null; + // 서명 + if($obj->signature) { + $signature = removeHackTag($obj->signature); + $signature_buff = sprintf('%s', $signature); + + $target_path = sprintf('files/member_extra_info/signature/%s/', getNumberingPath($obj->member_srl)); + if(!is_dir($target_path)) FileHandler::makeDir($target_path); + $target_filename = sprintf('%s%d.signature.php', $target_path, $obj->member_srl); + + FileHandler::writeFile($target_filename, $signature_buff); } } } - fclose($fp); + fclose($f); - $success_count += $inserted_count; - - if($manual_break) { - $this->add('total_count',$total_count); - $this->add('success_count',$success_count); - $this->add('readed_line',$read_line); - $this->add('is_finished','0'); - $this->setMessage(sprintf(Context::getLang('msg_importing'), $total_count, $success_count)); - } else { - $this->add('is_finished','1'); - $this->setMessage(sprintf(Context::getLang('msg_import_finished'), $success_count, $total_count)); - } + return $idx-1; } /** - * @brief 주어진 xml 파일을 파싱해서 회원 정보 입력 + * @brief 주어진 xml 파일을 파싱해서 쪽지 정보 입력 **/ - function importMessage($obj) { - // 보낸이/ 받는이의 member_srl을 구함 (존재하지 않으면 그냥 pass..) - if(!$obj->sender) return false; - $sender_args->user_id = $obj->sender; - $sender_output = executeQuery('member.getMemberInfo',$sender_args); - $sender_srl = $sender_output->data->member_srl; - if(!$sender_srl) return false; + function importMessage($key, $cur, $index_file) { + if(!$cur) $cur = 0; - $receiver_args->user_id = $obj->receiver; - if(!$obj->receiver) return false; - $receiver_output = executeQuery('member.getMemberInfo',$receiver_args); - $receiver_srl = $receiver_output->data->member_srl; - if(!$receiver_srl) return false; + // xmlParser객체 생성 + $oXmlParser = new XmlParser(); - // 보내는 사용자의 쪽지함에 넣을 쪽지 - $sender_args->sender_srl = $sender_srl; - $sender_args->receiver_srl = $receiver_srl; - $sender_args->message_type = 'S'; - $sender_args->title = $obj->title; - $sender_args->content = $obj->content; - $sender_args->readed = $obj->readed; - $sender_args->regdate = $obj->regdate; - $sender_args->readed_date = $obj->readed_date; - $sender_args->related_srl = getNextSequence(); - $sender_args->message_srl = getNextSequence(); - $sender_args->list_order = $sender_args->message_srl * -1; + // index파일을 염 + $f = fopen($index_file,"r"); - $output = executeQuery('member.sendMessage', $sender_args); - if(!$output->toBool()) return false; + // 이미 읽혀진 것은 패스 + for($i=0;$i<$cur;$i++) fgets($f, 1024); - // 받는 회원의 쪽지함에 넣을 쪽지 - $receiver_args->message_srl = $sender_args->related_srl; - $receiver_args->list_order = $sender_args->related_srl*-1; - $receiver_args->sender_srl = $sender_srl; - if(!$receiver_args->sender_srl) $receiver_args->sender_srl = $receiver_srl; - $receiver_args->receiver_srl = $receiver_srl; - $receiver_args->message_type = 'R'; - $receiver_args->title = $obj->title; - $receiver_args->content = $obj->content; - $receiver_args->readed = $obj->readed; - $receiver_args->regdate = $obj->regdate; - $receiver_args->readed_date = $obj->readed_date; - $output = executeQuery('member.sendMessage', $receiver_args); - if(!$output->toBool()) return false; + // 라인단위로 읽어들이면서 $cur보다 커지고 $cur+$this->unit_count개보다 작으면 중지 + for($idx=$cur;$idx<$cur+$this->unit_count;$idx++) { + if(feof($f)) break; - return true; + // 정해진 위치를 찾음 + $target_file = trim(fgets($f, 1024)); + + // 대상 파일을 읽여서 파싱후 입력 + $xmlObj = $oXmlParser->loadXmlFile($target_file); + @unlink($target_file); + if(!$xmlObj) continue; + + // 객체 정리 + $obj = null; + $obj->receiver = base64_decode($xmlObj->message->receiver->body); + $obj->sender = base64_decode($xmlObj->message->sender->body); + $obj->title = base64_decode($xmlObj->message->title->body); + $obj->content = base64_decode($xmlObj->message->content->body); + $obj->readed = base64_decode($xmlObj->message->readed->body)=='Y'?'Y':'N'; + $obj->regdate = base64_decode($xmlObj->message->regdate->body); + $obj->readed_date = base64_decode($xmlObj->message->readed_date->body); + $obj->receiver = base64_decode($xmlObj->message->receiver->body); + + // 보낸이/ 받는이의 member_srl을 구함 (존재하지 않으면 그냥 pass..) + if(!$obj->sender) continue; + $sender_args->user_id = $obj->sender; + $sender_output = executeQuery('member.getMemberInfo',$sender_args); + $sender_srl = $sender_output->data->member_srl; + if(!$sender_srl) continue; + + $receiver_args->user_id = $obj->receiver; + if(!$obj->receiver) continue; + $receiver_output = executeQuery('member.getMemberInfo',$receiver_args); + $receiver_srl = $receiver_output->data->member_srl; + if(!$receiver_srl) continue; + + // 보내는 사용자의 쪽지함에 넣을 쪽지 + $sender_args->sender_srl = $sender_srl; + $sender_args->receiver_srl = $receiver_srl; + $sender_args->message_type = 'S'; + $sender_args->title = $obj->title; + $sender_args->content = $obj->content; + $sender_args->readed = $obj->readed; + $sender_args->regdate = $obj->regdate; + $sender_args->readed_date = $obj->readed_date; + $sender_args->related_srl = getNextSequence(); + $sender_args->message_srl = getNextSequence(); + $sender_args->list_order = $sender_args->message_srl * -1; + + $output = executeQuery('member.sendMessage', $sender_args); + if($output->toBool()) { + // 받는 회원의 쪽지함에 넣을 쪽지 + $receiver_args->message_srl = $sender_args->related_srl; + $receiver_args->list_order = $sender_args->related_srl*-1; + $receiver_args->sender_srl = $sender_srl; + if(!$receiver_args->sender_srl) $receiver_args->sender_srl = $receiver_srl; + $receiver_args->receiver_srl = $receiver_srl; + $receiver_args->message_type = 'R'; + $receiver_args->title = $obj->title; + $receiver_args->content = $obj->content; + $receiver_args->readed = $obj->readed; + $receiver_args->regdate = $obj->regdate; + $receiver_args->readed_date = $obj->readed_date; + $output = executeQuery('member.sendMessage', $receiver_args); + } + } + + fclose($f); + + return $idx-1; } /** * @brief module.xml 형식의 데이터 import **/ - function procImporterAdminModuleImport() { - set_time_limit(0); - - $xml_file = Context::get('xml_file'); - $target_module = Context::get('target_module'); - $total_count = (int)Context::get('total_count'); - $success_count = (int)Context::get('success_count'); - $readed_line = (int)Context::get('readed_line'); - - // xml_file 경로가 없으면 에러~ - if(!$xml_file) return new Object(-1, 'msg_no_xml_file'); - - // local 파일 지정인데 파일이 없으면 역시 에러~ - if(!preg_match('/^http:/i',$xml_file) && (!preg_match("/\.xml$/i", $xml_file) || !file_exists($xml_file)) ) return new Object(-1,'msg_no_xml_file'); - + function importModule($key, $cur, $index_file, $module_srl) { // 필요한 객체 미리 생성 - $this->oDocumentController = &getController('document'); - $this->oDocumentModel = &getModel('document'); - $this->oCommentController = &getController('comment'); - $this->oCommentModel = &getModel('comment'); - $this->oTrackbackController = &getController('trackback'); - - // 타켓 모듈의 유무 체크 - if(!$target_module) return new Object(-1,'msg_invalid_request'); - $module_srl = $target_module; + $this->oXmlParser = new XmlParser(); // 타겟 모듈의 카테고리 정보 구함 - $category_list = $this->oDocumentModel->getCategoryList($module_srl); - if(count($category_list)) { - foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; - } else { - $category_list = $category_titles = array(); + $oDocumentModel = &getModel('document'); + $category_list = $category_titles = array(); + $category_list = $oDocumentModel->getCategoryList($module_srl); + if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; + + // 먼저 카테고리 정보를 입력함 + $category_file = preg_replace('/index$/i', 'category', $index_file); + if(file_exists($category_file)) { + $buff = FileHandler::readFile($category_file); + + // xmlParser객체 생성 + $xmlDoc = $this->oXmlParser->loadXmlFile($category_file); + + $categories = $xmlDoc->items->category; + if($categories) { + if(!is_array($categories)) $categories = array($categories); + $oDocumentController = &getController('document'); + foreach($categories as $k => $v) { + $category = trim(base64_decode($v->body)); + if(!$category || $category_titles[$category]) continue; + + $obj = null; + $obj->title = $category; + $obj->module_srl = $module_srl; + $output = $oDocumentController->insertCategory($obj); + } + $oDocumentController = &getController('document'); + $oDocumentController->makeCategoryFile($module_srl); + } + @unlink($category_file); } - // 이제부터 데이터를 가져오면서 처리 - $fp = $this->getFilePoint($xml_file); - if(!$fp) return new Object(-1,'msg_no_xml_file'); + $category_list = $category_titles = array(); + $category_list = $oDocumentModel->getCategoryList($module_srl); + if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; + + if(!$cur) $cur = 0; - $manual_break = false; - $obj = null; - $document_srl = null; + // index파일을 염 + $f = fopen($index_file,"r"); - $inserted_count = 0; + // 이미 읽혀진 것은 패스 + for($i=0;$i<$cur;$i++) fgets($f, 1024); - // 본문 데이터부터 처리 시작 - $read_line = 0; - while(!feof($fp)) { - $str = trim(fgets($fp, 1024)); + // 라인단위로 읽어들이면서 $cur보다 커지고 $cur+$this->unit_count개보다 작으면 중지 + for($idx=$cur;$idx<$cur+$this->unit_count;$idx++) { + if(feof($f)) break; - if($str == "") $read_line ++; - if($read_line < $readed_line) continue; + // 정해진 위치를 찾음 + $target_file = trim(fgets($f, 1024)); - // 한 아이템 준비 시작 - if(substr($str,0,6) == '') { - $obj = null; - $obj->module_srl = $module_srl; - $obj->document_srl = getNextSequence(); - continue; + if(!file_exists($target_file)) continue; - // 아이템 종료시 DB 입력 - } else if( $str == '') { - $obj->member_srl = 0; - if($this->importDocument($obj)) $inserted_count ++; - if($inserted_count >= 50) { - $manual_break = true; - break; + // 이제부터 데이터를 가져오면서 처리 + $fp = fopen($target_file,"r"); + if(!$fp) continue; + + $obj = null; + $obj->module_srl = $module_srl; + $obj->document_srl = getNextSequence(); + + $files = array(); + + $started = false; + $buff = null; + + // 본문 데이터부터 처리 시작 + while(!feof($fp)) { + $str = fgets($fp, 1024); + + // 한 아이템 준비 시작 + if(trim($str) == '') { + $started = true; + + // 엮인글 입력 + } else if(substr($str,0,11) == 'trackback_count = $this->importTrackbacks($fp, $module_srl, $obj->document_srl); + continue; + + // 댓글 입력 + } else if(substr($str,0,9) == 'comment_count = $this->importComments($fp, $module_srl, $obj->document_srl); + continue; + + // 첨부파일 입력 + } else if(substr($str,0,9) == 'uploaded_count = $this->importAttaches($fp, $module_srl, $obj->document_srl, $files); + continue; + + // 추가 변수 시작 일 경우 + } elseif(trim($str) == '') { + $this->importExtraVars($fp, $obj); + continue; } - // posts 태그 체크 (전체 개수를 구함) - } else if(substr($str,0,6)=='') { - $manual_break = false; - break; + $xmlDoc = $this->oXmlParser->parse($buff); + + $category = base64_decode($xmlDoc->post->category->body); + if($category_titles[$category]) $obj->category_srl = $category_titles[$category]; - // 카테고리 입력 - } else if($str == '') { - $this->importCategoris($fp, $module_srl, $category_list, $category_titles); - continue; + $obj->member_srl = 0; - // 엮인글 입력 - } else if(substr($str,0,11) == 'trackbacks = $this->importTrackbacks($fp); + $obj->is_notice = base64_decode($xmlDoc->post->is_notice->body)=='Y'?'Y':'N'; + $obj->is_secret = base64_decode($xmlDoc->post->is_secret->body)=='Y'?'Y':'N'; + $obj->title = base64_decode($xmlDoc->post->title->body); + $obj->content = base64_decode($xmlDoc->post->content->body); + $obj->readed_count = base64_decode($xmlDoc->post->readed_count->body); + $obj->voted_count = base64_decode($xmlDoc->post->voted_count->body); + $obj->password = base64_decode($xmlDoc->post->password->body); + $obj->user_name = $obj->nick_name = base64_decode($xmlDoc->post->nick_name->body); + $obj->user_id = base64_decode($xmlDoc->post->user_id->body); + $obj->email_address = base64_decode($xmlDoc->post->email->body); + $obj->homepage = base64_decode($xmlDoc->post->homepage->body); + if($obj->homepage && !preg_match('/^http:\/\//i',$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage; + $obj->tags = base64_decode($xmlDoc->post->tags->body); + $obj->regdate = base64_decode($xmlDoc->post->regdate->body); + $obj->last_update = base64_decode($xmlDoc->post->update->body); + if(!$obj->last_update) $obj->last_update = $obj->regdate; + $obj->ipaddress = base64_decode($xmlDoc->post->ipaddress->body); + $obj->list_order = $obj->update_order = $obj->document_srl*-1; + $obj->allow_comment = base64_decode($xmlDoc->post->allow_comment->body)!='N'?'Y':'N'; + $obj->lock_comment = base64_decode($xmlDoc->post->lock_comment->body)=='Y'?'Y':'N'; + $obj->allow_trackback = base64_decode($xmlDoc->post->allow_trackback->body)!='N'?'Y':'N'; + $obj->notify_message = base64_decode($xmlDoc->post->is_notice->body); - // 댓글 입력 - } else if(substr($str,0,9) == 'comments = $this->importComments($fp); - - // 첨부파일 입력 - } else if(substr($str,0,9) == 'attaches = $this->importAttaches($fp); - - // 추가 변수 시작 일 경우 - } elseif($str == '') { - $this->importExtraVars($fp, $obj); - - // 변수 체크 - } else { - $buff .= $str; - $pos = strpos($buff, '>'); - $key = substr($buff, 1, $pos-1); - if(substr($buff, -1 * ( strlen($key)+3)) == '') { - $val = base64_decode(substr($buff, $pos, strlen($buff)-$pos*2-2)); - if($key == 'category' && $category_titles[$val]) $obj->category_srl = $category_titles[$val]; - else $obj->{$key} = $val; - $buff = null; + // content 정보 변경 (첨부파일) + if(count($files)) { + foreach($files as $key => $val) { + $obj->content = preg_replace('/(src|href)\=(["\']?)'.preg_quote($key).'(["\']?)/i','$1="'.$val.'"',$obj->content); } } + + $output = executeQuery('document.insertDocument', $obj); + + if($output->toBool() && $obj->tags) { + $tag_list = explode(',',$obj->tags); + $tag_count = count($tag_list); + for($i=0;$i<$tag_count;$i++) { + $args = null; + $args->tag_srl = getNextSequence(); + $args->module_srl = $module_srl; + $args->document_srl = $obj->document_srl; + $args->tag = trim($tag_list[$i]); + $args->regdate = $obj->regdate; + if(!$args->tag) continue; + $output = executeQuery('tag.insertTag', $args); + } + + } + + fclose($fp); + @unlink($target_file); } - fclose($fp); + fclose($f); - $success_count += $inserted_count; - - if($manual_break) { - $this->add('total_count',$total_count); - $this->add('success_count',$success_count); - $this->add('readed_line',$read_line); - $this->add('is_finished','0'); - $this->setMessage(sprintf(Context::getLang('msg_importing'), $total_count, $success_count)); - } else { - $this->add('is_finished','1'); - $this->setMessage(sprintf(Context::getLang('msg_import_finished'), $success_count, $total_count)); - } + return $idx-1; } /** * @brief 엮인글 정리 **/ - function importTrackbacks($fp) { - $trackbacks = array(); - $obj = null; + function importTrackbacks($fp, $module_srl, $document_srl) { + $started = false; + $buff = null; + $cnt = 0; while(!feof($fp)) { - $str = trim(fgets($fp, 1024)); - if($str == '') break; - elseif($str == '') { + + $str = fgets($fp, 1024); + + // 이면 중단 + if(trim($str) == '') break; + + // 면 시작 + if(trim($str) == '') $started = true; + + if($started) $buff .= $str; + + // 이면 DB에 입력 + if(trim($str) == '') { + $xmlDoc = $this->oXmlParser->parse($buff); + $obj = null; - continue; + $obj->trackback_srl = getNextSequence(); + $obj->module_srl = $module_srl; + $obj->document_srl = $document_srl; + $obj->url = base64_decode($xmlDoc->trackback->url->body); + $obj->title = base64_decode($xmlDoc->trackback->title->body); + $obj->blog_name = base64_decode($xmlDoc->trackback->blog_name->body); + $obj->excerpt = base64_decode($xmlDoc->trackback->excerpt->body); + $obj->regdate = base64_decode($xmlDoc->trackback->regdate->body); + $obj->ipaddress = base64_decode($xmlDoc->trackback->ipaddress->body); + $obj->list_order = -1*$obj->trackback_srl; + $output = executeQuery('trackback.insertTrackback', $obj); + if($output->toBool()) $cnt++; - } elseif($str == '') { - $trackbacks[] = $obj; - continue; - } - - $buff .= $str; - $pos = strpos($buff, '>'); - $key = substr($buff, 1, $pos-1); - if(substr($buff, -1 * ( strlen($key)+3)) == '') { - $val = base64_decode(substr($buff, $pos, strlen($buff)-$pos*2-2)); - $obj->{$key} = $val; $buff = null; + $started = false; } } - - return $trackbacks; + return $cnt; } /** * @brief 댓글 정리 **/ - function importComments($fp) { - $comments = array(); - $obj = null; + function importComments($fp, $module_srl, $document_srl) { + $started = false; + $buff = null; + $cnt = 0; + + $sequences = array(); + while(!feof($fp)) { - $str = trim(fgets($fp, 1024)); - // 댓글 전체 끝 - if($str == '') break; - // 개별 댓글 시작 - elseif($str == '') { + $str = fgets($fp, 1024); + + // 이면 중단 + if(trim($str) == '') break; + + // 면 시작 + if(trim($str) == '') { + $started = true; $obj = null; - continue; - - // 댓글 끝 - } elseif($str == '') { - $comments[] = $obj; - continue; - - // 첨부파일이 있을때 - } else if(substr($str,0,9) == 'attaches = $this->importAttaches($fp); + $obj->comment_srl = getNextSequence(); + $files = array(); } - $buff .= $str; - $pos = strpos($buff, '>'); - $key = substr($buff, 1, $pos-1); - if(substr($buff, -1 * ( strlen($key)+3)) == '') { - $val = base64_decode(substr($buff, $pos, strlen($buff)-$pos*2-2)); - $obj->{$key} = $val; + // attaches로 시작하면 첨부파일 시작 + if(substr($str,0,9) == 'uploaded_count = $this->importAttaches($fp, $module_srl, $obj->comment_srl, $files); + continue; + } + + if($started) $buff .= $str; + + // 이면 DB에 입력 + if(trim($str) == '') { + $xmlDoc = $this->oXmlParser->parse($buff); + + $sequence = base64_decode($xmlDoc->comment->sequence->body); + $sequences[$sequence] = $obj->comment_srl; + $parent = base64_decode($xmlDoc->comment->parent->body); + + $obj->module_srl = $module_srl; + + if($parent) $obj->parent_srl = $sequences[$parent]; + else $obj->parent_srl = 0; + + $obj->document_srl = $document_srl; + $obj->is_secret = base64_decode($xmlDoc->comment->is_secret->body)=='Y'?'Y':'N'; + $obj->notify_message = base64_decode($xmlDoc->comment->notify_message->body)=='Y'?'Y':'N'; + $obj->content = base64_decode($xmlDoc->comment->content->body); + $obj->voted_count = base64_decode($xmlDoc->comment->voted_count->body); + $obj->password = base64_decode($xmlDoc->comment->password->body); + $obj->user_name = $obj->nick_name = base64_decode($xmlDoc->comment->nick_name->body); + $obj->user_id = base64_decode($xmlDoc->comment->user_id->body); + $obj->member_srl = 0; + $obj->email_address = base64_decode($xmlDoc->comment->email->body); + $obj->homepage = base64_decode($xmlDoc->comment->homepage->body); + $obj->regdate = base64_decode($xmlDoc->comment->regdate->body); + $obj->last_update = base64_decode($xmlDoc->comment->update->body); + if(!$obj->last_update) $obj->last_update = $obj->regdate; + $obj->ipaddress = base64_decode($xmlDoc->comment->ipaddress->body); + $obj->list_order = $obj->comment_srl*-1; + + // content 정보 변경 (첨부파일) + if(count($files)) { + foreach($files as $key => $val) { + $obj->content = preg_replace('/(src|href)\=(["\']?)'.preg_quote($key).'(["\']?)/i','$1="'.$val.'"',$obj->content); + } + } + + // 댓글 목록 부분을 먼저 입력 + $list_args = null; + $list_args->comment_srl = $obj->comment_srl; + $list_args->document_srl = $obj->document_srl; + $list_args->module_srl = $obj->module_srl; + $list_args->regdate = $obj->regdate; + + // 부모댓글이 없으면 바로 데이터를 설정 + if(!$obj->parent_srl) { + $list_args->head = $list_args->arrange = $obj->comment_srl; + $list_args->depth = 0; + + // 부모댓글이 있으면 부모글의 정보를 구해옴 + } else { + // 부모댓글의 정보를 구함 + $parent_args->comment_srl = $obj->parent_srl; + $parent_output = executeQuery('comment.getCommentListItem', $parent_args); + + // 부모댓글이 존재하지 않으면 return + if(!$parent_output->toBool() || !$parent_output->data) continue; + $parent = $parent_output->data; + + $list_args->head = $parent->head; + $list_args->depth = $parent->depth+1; + if($list_args->depth<2) $list_args->arrange = $obj->comment_srl; + else { + $list_args->arrange = $parent->arrange; + $output = executeQuery('comment.updateCommentListArrange', $list_args); + if(!$output->toBool()) return $output; + } + } + + $output = executeQuery('comment.insertCommentList', $list_args); + if($output->toBool()) { + $output = executeQuery('comment.insertComment', $obj); + if($output->toBool()) $cnt++; + } + $buff = null; + $started = false; } } - - return $comments; + return $cnt; } /** * @brief 첨부파일 정리 **/ - function importAttaches($fp) { - $attaches = array(); - $obj = null; - $index = 0; + function importAttaches($fp, $module_srl, $upload_target_srl, &$files) { + $uploaded_count = 0; + + $started = false; + $buff = null; while(!feof($fp)) { $str = trim(fgets($fp, 1024)); - if($str == '') break; - elseif($str == '') { - $obj = null; - continue; - } elseif($str == '') { - $attaches[] = $obj; - continue; + // 로 끝나면 중단 + if(trim($str) == '') break; - // 첨부파일 - } else if($str == '') { - // binary buffer일 경우 임의의 위치에 파일을 저장시켜 놓고 그 파일의 경로를 return - $filename = $this->readFileBuff($fp, 'file'); - $obj->file = $filename; + // 로 시작하면 첨부파일 수집 + if(trim($str) == '') { + $file_obj = null; + $file_obj->file_srl = getNextSequence(); + $file_obj->upload_target_srl = $upload_target_srl; + $file_obj->module_srl = $module_srl; + + $started = true; + $buff = null; + // 로 시작하면 xml파일내의 첨부파일로 처리 + } else if(trim($str) == '') { + $file_obj->file = $this->saveTemporaryFile($fp); continue; } - $buff .= $str; - $pos = strpos($buff, '>'); - $key = substr($buff, 1, $pos-1); - if(substr($buff, -1 * ( strlen($key)+3)) == '') { - $val = base64_decode(substr($buff, $pos, strlen($buff)-$pos*2-2)); - $obj->{$key} = $val; - $buff = null; + if($started) $buff .= $str; + + // 로 끝나면 첨부파일 정리 + if(trim($str) == '') { + $xmlDoc = $this->oXmlParser->parse($buff.$str); + + $file_obj->source_filename = base64_decode($xmlDoc->attach->filename->body); + $file_obj->download_count = base64_decode($xmlDoc->attach->download_count->body); + + if(!$file_obj->file) { + $url = base64_decode($xmlDoc->attach->url->body); + $path = base64_decode($xmlDoc->attach->path->body); + if($path && file_exists($path)) $file_obj->file = $path; + else { + $file_obj->file = $this->getTmpFilename(); + FileHandler::getRemoteFile($url, $file_obj->file); + } + } + + // 이미지인지 기타 파일인지 체크하여 upload path 지정 + if(preg_match("/\.(jpg|jpeg|gif|png|wmv|wma|mpg|mpeg|avi|swf|flv|mp3|asaf|wav|asx|midi|asf)$/i", $file_obj->source_filename)) { + $path = sprintf("./files/attach/images/%s/%s/", $module_srl,$upload_target_srl); + $filename = $path.$file_obj->source_filename; + $file_obj->direct_download = 'Y'; + } else { + $path = sprintf("./files/attach/binaries/%s/%s/", $module_srl, $upload_target_srl); + $filename = $path.md5(crypt(rand(1000000,900000), rand(0,100))); + $file_obj->direct_download = 'N'; + } + + // 디렉토리 생성 + if(!FileHandler::makeDir($path)) continue; + + if(preg_match('/^\.\/files\/cache\/tmp/i',$file_obj->file)) @rename($file_obj->file, $filename); + else @copy($file_obj->file, $filename); + + // DB입력 + unset($file_obj->file); + $file_obj->uploaded_filename = $filename; + $file_obj->file_size = filesize($filename); + $file_obj->comment = NULL; + $file_obj->member_srl = 0; + $file_obj->sid = md5(rand(rand(1111111,4444444),rand(4444445,9999999))); + $file_obj->isvalid = 'Y'; + $output = executeQuery('file.insertFile', $file_obj); + + if($output->toBool()) { + $uploaded_count++; + $tmp_obj = null; + $tmp_obj->source_filename = $file_obj->source_filename; + if($file_obj->direct_download == 'Y') $files[$file_obj->source_filename] = $file_obj->uploaded_filename; + else $files[$file_obj->source_filename] = getUrl('','module','file','act','procFileDownload','file_srl',$file_obj->file_srl,'sid',$file_obj->sid); + } + } } - - return $attaches; + return $uploaded_count; } /** - * @brief 카테고리 정보 가져오기 + * @biref 임의로 사용할 파일이름을 return **/ - function importCategoris($fp, $module_srl, &$category_list, &$category_titles) { + function getTmpFilename() { + $path = "./files/cache/tmp"; + if(!is_dir($path)) FileHandler::makeDir($path); + $filename = sprintf("%s/%d", $path, rand(11111111,99999999)); + if(file_exists($filename)) $filename .= rand(111,999); + return $filename; + } + + /** + * @brief 특정 파일포인트로부터 key에 해당하는 값이 나타날때까지 buff를 읽음 + **/ + function saveTemporaryFile($fp) { + $temp_filename = $this->getTmpFilename(); + $f = fopen($temp_filename, "w"); + + $buff = ''; while(!feof($fp)) { $str = trim(fgets($fp, 1024)); - if($str == '') break; + if(trim($str) == '') break; - $category = base64_decode(substr($str,10,-11)); - if($category_titles[$category]) continue; + $buff .= $str; - $obj = null; - $obj->title = $category; - $obj->module_srl = $module_srl; - $output = $this->oDocumentController->insertCategory($obj); - } - - $category_list = $this->oDocumentModel->getCategoryList($module_srl); - if(count($category_list)) { - foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; - } else { - $category_list = $category_titles = array(); + if(substr($buff,-7)=='') { + fwrite($f, base64_decode(substr($buff, 6, -7))); + $buff = ''; + } } + fclose($f); + return $temp_filename; } + /** * @brief 게시글 추가 변수 설정 **/ @@ -661,7 +836,7 @@ $index = 1; while(!feof($fp)) { $str = trim(fgets($fp, 1024)); - if($str == '') break; + if(trim($str) == '') break; $buff .= $str; $pos = strpos($buff, '>'); @@ -673,523 +848,5 @@ } } } - - /** - * @brief 게시글 입력 - **/ - function importDocument($obj) { - // 본문, 댓글, 엮인글, 첨부파일별로 변수 정리 - $comments = $obj->comments; - $trackbacks = $obj->trackbacks; - $attaches = $obj->attaches; - unset($obj->comments); - unset($obj->trackbacks); - unset($obj->attaches); - - // 첨부파일 미리 등록 - if(count($attaches)) { - foreach($attaches as $key => $val) { - $filename = $val->filename; - $download_count = (int)$val->download_count; - $file = $val->file; - - if(!file_exists($file)) continue; - - $file_info['tmp_name'] = $file; - $file_info['name'] = $filename; - - $oFileController = &getController('file'); - $file_output = $oFileController->insertFile($file_info, $obj->module_srl, $obj->document_srl, $download_count, true); - - // 컨텐츠의 내용 수정 (이미지 첨부파일 관련) - if($file_output->toBool()) { - if($file_output->get('direct_download') == 'Y') { - $obj->content = str_replace($filename, sprintf('./files/attach/images/%s/%s/%s', $obj->module_srl, $obj->document_srl, $filename), $obj->content); - } else { - $oFileModel = &getModel('file'); - $url = $oFileModel->getDownloadUrl($file_output->get('file_srl'), $file_output->get('sid')); - $obj->content = str_replace('"'.$filename.'"', $url, $obj->content); - } - } - @unlink($file); - } - } - - // 게시글 등록 - //$obj->member_srl = 0; - $obj->password_is_hashed = true; - $output = $this->oDocumentController->insertDocument($obj, true); - - // 등록 실패시 첨부파일을 일단 모두 지움 - if(!$output->toBool()) { - return false; - } - - // 댓글 부모/자식 관계 정리하기 위한 변수 - $comment_parent_srls = array(); - - // 댓글 등록 - if(count($comments)) { - $last_comment_updator = ''; - foreach($comments as $key => $val) { - // 댓글 내용 정리 - $comment_args->comment_srl = getNextSequence(); - $comment_parent_srls[$val->sequence] = $comment_args->comment_srl; - if($val->parent) $comment_args->parent_srl = $comment_parent_srls[$val->parent]; - $comment_args->module_srl = $obj->module_srl; - $comment_args->document_srl = $obj->document_srl; - $comment_args->content = $val->content; - $comment_args->password = $val->password; - $comment_args->nick_name = $val->nick_name; - $comment_args->user_id = $val->user_id; - $comment_args->user_name = $val->user_name; - $comment_args->member_srl = 0; - $comment_args->email_address = $val->email; - $comment_args->homepage = $val->homepage; - $comment_args->regdate = $val->regdate; - $comment_args->ipaddress = $val->ipaddress; - - $last_comment_updator = $val->nick_name; - - // 첨부파일 미리 등록 - if(count($val->attaches)) { - foreach($val->attaches as $k => $v) { - $filename = $v->filename; - $download_count = (int)$v->download_count; - $file = $v->file; - - if(!file_exists($file)) continue; - - $file_info['tmp_name'] = $file; - $file_info['name'] = $filename; - - $oFileController = &getController('file'); - $file_output = $oFileController->insertFile($file_info, $obj->module_srl, $comment_args->comment_srl, $download_count, true); - - - // 컨텐츠의 내용 수정 (이미지 첨부파일 관련) - if($file_output->toBool()) { - if($file_output->get('direct_download') == 'Y') { - $comment_args->content = str_replace($filename, sprintf('./files/attach/images/%s/%s/%s', $comment_args->module_srl, $comment_args->comment_srl, $filename), $comment_args->content); - } else { - $oFileModel = &getModel('file'); - $url = $oFileModel->getDownloadUrl($file_output->get('file_srl'), $file_output->get('sid')); - $comment_args->content = str_replace('"'.$filename.'"', $url, $comment_args->content); - } - } - @unlink($file); - } - } - - $comment_output = $this->oCommentController->insertComment($comment_args, true); - } - - // 댓글 수 update - $comment_count = $this->oCommentModel->getCommentCount($obj->document_srl); - $update_output = $this->oDocumentController->updateCommentCount($obj->document_srl, $comment_count, $last_comment_updator, true); - } - - // 엮인글 등록 - if(count($trackbacks)) { - foreach($trackbacks as $key => $val) { - $val->module_srl = $obj->module_srl; - $val->document_srl = $obj->document_srl; - $val->trackback_srl = getNextSequence(); - $val->list_order = $val->trackback_srl*-1; - $trackback_output = executeQuery('trackback.insertTrackback', $val); - //$trackback_output = $this->oTrackbackController->insertTrackback($val, true); - } - $oTrackbackModel = &getModel('trackback'); - $trackback_count = $oTrackbackModel->getTrackbackCount($obj->document_srl); - $this->oDocumentController->updateTrackbackCount($obj->document_srl, $trackback_count); - } - - return true; - } - - - /** - * @brief 파일포인터 return (local or http wrapper) - **/ - function getFilePoint($filename) { - $fp = null; - if(preg_match('/^http:/i', $filename)) { - $url_info = parse_url($filename); - if(!$url_info['port']) $url_info['port'] = 80; - if(!$url_info['path']) $url_info['path'] = '/'; - - $fp = @fsockopen($url_info['host'], $url_info['port']); - if($fp) { - - // 한글 파일이 있으면 한글파일 부분만 urlencode하여 처리 (iconv 필수) - $path = $url_info['path']; - if(preg_match('/[\xEA-\xED][\x80-\xFF]{2}/', $path)&&function_exists('iconv')) { - $path_list = explode('/',$path); - $cnt = count($path_list); - $filename = $path_list[$cnt-1]; - $filename = urlencode(iconv("UTF-8","EUC-KR",$filename)); - $path_list[$cnt-1] = $filename; - $path = implode('/',$path_list); - $url_info['path'] = $path; - } - - $header = sprintf("GET %s?%s HTTP/1.0\r\nHost: %s\r\nReferer: %s://%s\r\nConnection: Close\r\n\r\n", $url_info['path'], $url_info['query'], $url_info['host'], $url_info['scheme'], $url_info['host']); - @fwrite($fp, $header); - while(!feof($fp)) { - $str = fgets($fp, 1024); - if(!trim($str)) break; - } - } - } else { - $fp = fopen($filename,"r"); - } - - return $fp; - } - - /** - * @biref 임의로 사용할 파일이름을 return - **/ - function getTmpFilename($key) { - $path = "./files/cache/tmp"; - if(!is_dir($path)) FileHandler::makeDir($path); - $filename = sprintf("%s/%s.%d", $path, $key, rand(11111111,99999999)); - if(file_exists($filename)) $filename .= rand(111,999); - return $filename; - } - - /** - * @brief 특정 파일포인트로부터 key에 해당하는 값이 나타날때까지 buff를 읽음 - **/ - function readFileBuff($fp,$key) { - $temp_filename = $this->getTmpFilename($key); - $f = fopen($temp_filename, "w"); - - $buff = ''; - while(!feof($fp)) { - $str = trim(fgets($fp, 1024)); - if($str == sprintf('', $key)) break; - - $buff .= $str; - - if(substr($buff, -7) == '') { - fwrite($f, base64_decode(substr($buff, 6, -7))); - $buff = null; - } - } - fclose($f); - return $temp_filename; - } - - /** - * @brief TTXML import - **/ - function procImporterAdminTTXMLImport() { - set_time_limit(0); - - $xml_file = Context::get('xml_file'); - $target_module = Context::get('target_module'); - $user_id = Context::get('user_id'); - if(!$user_id) return new Object(-1,'msg_invalid_request'); - - $oMemberModel = &getModel('member'); - $member_info = $oMemberModel->getMemberInfoByUserID($user_id); - - $total_count = 0; - $success_count = 0; - - // xml_file 경로가 없으면 에러~ - if(!$xml_file) return new Object(-1, 'msg_no_xml_file'); - - // local 파일 지정인데 파일이 없으면 역시 에러~ - if(!preg_match('/^http:/i',$xml_file) && (!preg_match("/\.xml$/i", $xml_file) || !file_exists($xml_file)) ) return new Object(-1,'msg_no_xml_file'); - - // 필요한 객체 미리 생성 - $this->oDocumentController = &getController('document'); - $this->oDocumentModel = &getModel('document'); - $this->oCommentController = &getController('comment'); - $this->oCommentModel = &getModel('comment'); - $this->oTrackbackController = &getController('trackback'); - - // 타켓 모듈의 유무 체크 - if(!$target_module) return new Object(-1,'msg_invalid_request'); - $module_srl = $target_module; - - // 타겟 모듈의 카테고리 정보 구함 - $category_list = $this->oDocumentModel->getCategoryList($module_srl); - if(count($category_list)) { - foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; - } else { - $category_list = $category_titles = array(); - } - - // 이제부터 데이터를 가져오면서 처리 - $fp = $this->getFilePoint($xml_file); - if(!$fp) return new Object(-1,'msg_no_xml_file'); - - $manual_break = false; - $obj = null; - $attaches = array(); - $document_srl = null; - - $inserted_count = 0; - - ob_start(); - - $this->oXmlParser = new XmlParser(); - - // 본문 데이터부터 처리 시작 - $i=0; - $started = $category_started = $post_started = false; - $category_buff = ''; - $manual_break = false; - while(!$manual_break && !feof($fp)) { - $str = fgets($fp, 1024); - - if(substr($str,0,7)=='') $str = substr($str,7); - if(substr($str,0,6)=='') $str = substr($str,6); - - if(substr($str,0,10)=='' || substr($str,0,6) == '') { - $category_started = true; - $category_buff .= $str; - } - - // ') { - $str = substr($str,7); - - // 게시글 처리 - $post_buff .= ''; - $xml_doc = $this->oXmlParser->parse($post_buff); - $post = $xml_doc->post; - - if($post->visibility->body=='public') { - $obj = null; - $obj->module_srl = $module_srl; - $obj->document_srl = getNextSequence(); - $obj->title = $post->title->body; - $obj->content = str_replace('[##_ATTACH_PATH_##]/','',$post->content->body); - $obj->content = preg_replace_callback('!\[##_1C\|([^\|]*)\|([^\|]*)\|(.*?)_##\]!is', array($this, '_replaceTTImgTag'), $obj->content); - $obj->content = nl2br($obj->content); - $obj->password = md5($post->password->body); - $obj->allow_comment = $post->acceptcomment->body==1?'Y':'N'; - $obj->allow_trackback= $post->accepttrackback->body==1?'Y':'N'; - $obj->regdate = date("YmdHis",$post->created->body); - $obj->last_update = date("YmdHis",$post->modified->body); - - $category = trim($post->category->body); - if($category) { - $tmp_category = explode('/',$category); - if(count($tmp_category)>1) $category = $tmp_category[1]; - $obj->category_srl = (int)$category_titles[$category]; - if(!$obj->category_srl) { - $tmp = array_values($category_titles); - $obj->category_srl = (int)$tmp[0]; - } - } - $obj->user_id = $member_info->user_id; - $obj->nick_name = $member_info->nick_name; - $obj->user_name = $member_info->user_name; - $obj->member_srl = $member_info->member_srl; - - // 댓글 - $obj->comments = $this->importTTComment($post->comment); - - // 꼬리표 - $tags = $post->tag; - if(!is_array($tags)) $tags = array($tags); - if(count($tags)) { - $tag_list = array(); - foreach($tags as $key => $val) { - $tag = trim($val->body); - if(!$tag) continue; - $tag_list[] = $tag; - } - if(count($tag_list)) $obj->tags = implode(',',$tag_list); - } - - // 엮인글 - if($post->trackback) { - $trackbacks = $post->trackback; - if(!is_array($trackbacks)) $trackbacks = array($trackbacks); - if(count($trackbacks)) { - foreach($trackbacks as $key => $val) { - $tobj = null; - $tobj->url = $val->url->body; - $tobj->title = $val->title->body; - $tobj->blog_name = $val->site->body; - $tobj->excerpt = $val->excerpt->body; - $tobj->regdate = date("YmdHis",$val->received->body); - $tobj->ipaddress = $val->ip->body; - $obj->trackbacks[] = $tobj; - } - } - } - - // 첨부파일 - $obj->attaches = $attaches; - - $total_count ++; - if($this->importDocument($obj)) $success_count ++; - } - - // 새로운 게시글을 위한 처리 - $post_started = false; - $obj = null; - $post_buff = ''; - $attaches = array(); - - // 만약 글입력후 oXmlParser->parse(''.$category_buff.''); - - if($xml_doc->category) { - $this->insertTTCategory($xml_doc, 0, $module_srl, $category_titles); - - // 입력완료 후 카테고리 xml파일 재생성 - $this->oDocumentController->makeCategoryFile($module_srl); - $xml_doc = null; - } - - $category_buff = null; - } - - $post_started = true; - } - - // 게시글 버퍼링중일때 처리 - if($post_started) { - // 첨부파일의 경우 별도로 버퍼링을 하지 않고 직접 파일에 기록해야 함 - if(substr($str,0,12)=='importTTAttaches($fp, $str); - else $post_buff .= $str; - } - } - } - fclose($fp); - - $output = ob_get_clean(); - - $this->add('is_finished','1'); - $this->add('total_count',$total_count); - $this->add('success_count',$success_count); - $this->add('readed_line',0); - $this->setMessage(sprintf(Context::getLang('msg_import_finished'), $success_count, $total_count)); - } - - /** - * @brief ttxml의 자체 img 태그를 치환 - **/ - function _replaceTTImgTag($matches) { - return sprintf("\"%s\"", $matches[1], str_replace("\"","\\\"",$matches[3])); - } - - /** - * @brief TTXML에 맞게 category정보 입력 - **/ - function insertTTCategory($xml_doc, $parent_srl =0, $module_srl, &$category_titles) { - // category element가 없으면 pass - if(!$xml_doc->category) return; - $categories = $xml_doc->category; - - // 하나만 있을 경우 배열 처리 - if(!is_array($categories)) $categories = array($categories); - - // ttxml에서는 priority순서로 오는게 아니라서 정렬 - foreach($categories as $obj) { - $title = trim($obj->name->body); - $priority = $obj->priority->body; - $root = $obj->root->body; - if($root==1) continue; - $category_list[$priority]->title = $title; - $category_list[$priority]->category = $obj->category; - } - - // 데이터 입력 - foreach($category_list as $obj) { - if(!$category_titles[$obj->title]) { - $args = null; - $args->title = $obj->title; - $args->parent_srl = $parent_srl; - $args->module_srl = $module_srl; - $output = $this->oDocumentController->insertCategory($args); - if($output->toBool()) $category_titles[$args->title] = $output->get('category_srl'); - $output = null; - } - - $this->insertTTCategory($obj, $category_titles[$obj->title], $module_srl, $category_titles); - - } - } - - /** - * @brief TTXML 첨부파일 정리 - **/ - function importTTAttaches($fp, $buff) { - if(substr(trim($buff), -13) != '') { - while(!feof($fp)) { - $buff .= fgets($fp, 1024); - if(substr(trim($buff), -13) == '') break; - } - } - - $xml_doc = $this->oXmlParser->parse($buff); - $buff = ''; - - $obj = null; - $obj->filename = $xml_doc->attachment->name->body; - $obj->file = $this->getTmpFilename('file'); - $obj->download_count = $xml_doc->attachment->downloads->body; - - $f = fopen($obj->file, "w"); - fwrite($f, base64_decode($xml_doc->attachment->content->body)); - fclose($f); - - return $obj; - } - - /** - * @brief TTXML 댓글 정리 - **/ - function importTTComment($comment) { - if(!$comment) return; - if(!is_array($comment)) $comment = array($comment); - - $comments = array(); - - $sequence = 0; - foreach($comment as $key => $val) { - $obj = null; - $obj->sequence = $sequence; - - if($val->commenter->attrs->id) $obj->parent = $sequence-1; - - $obj->is_secret = $val->secret->body==1?'Y':'N'; - $obj->content = nl2br($val->content->body); - $obj->password = $val->password->body; - $obj->nick_name = $val->commenter->name->body; - $obj->homepage = $val->commenter->homepage->body; - $obj->regdate = date("YmdHis",$val->written->body); - $obj->ipaddress = $val->commenter->ip->body; - $comments[] = $obj; - - $sequence++; - } - return $comments; - } - } ?> diff --git a/modules/importer/importer.admin.view.php b/modules/importer/importer.admin.view.php index 2bd362f10..f0560ff3f 100644 --- a/modules/importer/importer.admin.view.php +++ b/modules/importer/importer.admin.view.php @@ -50,6 +50,7 @@ $template_filename = "index"; break; } + $this->setTemplateFile($template_filename); } diff --git a/modules/importer/lang/en.lang.php b/modules/importer/lang/en.lang.php index cb42af6b2..119a2ee5c 100644 --- a/modules/importer/lang/en.lang.php +++ b/modules/importer/lang/en.lang.php @@ -8,6 +8,7 @@ // words for button $lang->cmd_sync_member = 'Synchronize'; $lang->cmd_continue = 'Continue'; + $lang->preprocessing = '데이터 이전을 위한 사전 준비중입니다.'; // items $lang->importer = 'Transfer Zeroboard Data'; @@ -51,7 +52,7 @@ $lang->about_ttxml_user_id = 'Please input user ID to set as author on transfering TTXML. (user ID must be already signed up)'; $lang->about_type_module = 'If you are transfering the board or articles information, select this option'; $lang->about_type_syncmember = 'If you are trying to synchronize the member information after transfering member and article information, select this option'; - $lang->about_importer = "You can transfer Zeroboard4, Zeroboard5 Beta or other program's data into ZeroboardXE's data.\nIn order to tranfer, you have to use XML Exporter to convert the data you want into XML File then upload it."; + $lang->about_importer = "You can transfer Zeroboard4, Zeroboard5 Beta or other program's data into ZeroboardXE's data.\nIn order to tranfer, you have to use XML Exporter to convert the data you want into XML File then upload it."; $lang->about_target_path = "To get attachments from Zeroboard4, please input the address where Zeroboard4 is installed.\nIf it is located in the same server, input Zeroboard4's path such as /home/USERID/public_html/bbs\nIf it is not located in the same server, input the address where Zeroboard4 is installed. ex. http://Domain/bbs"; ?> diff --git a/modules/importer/lang/es.lang.php b/modules/importer/lang/es.lang.php index a058759ba..776021ae6 100644 --- a/modules/importer/lang/es.lang.php +++ b/modules/importer/lang/es.lang.php @@ -8,6 +8,7 @@ // Palabras para los botones $lang->cmd_sync_member = 'Sincronizar'; $lang->cmd_continue = 'Continuar'; + $lang->preprocessing = '데이터 이전을 위한 사전 준비중입니다.'; // Especificaciones $lang->importer = 'Transferir los datos de zeroboard'; @@ -51,7 +52,7 @@ $lang->about_ttxml_user_id = 'Por favor, de entrada ID de usuario establecer como autor de la transferencia de TTXML. (Identificación de usuario debe ser firmado ya en marcha)'; $lang->about_type_module = 'Seleccione esta opción si estas transfeririendo información del documento de los tableros'; $lang->about_type_syncmember = 'Seleccione esta opción cuando tenga que sincronizar la información del usuario luego de haber transferido la información del usuario y del artículo.'; - $lang->about_importer = "Es posible trasferir los datos de Zeroboard4, zb5beta o de otros programas a ZeroBoardXE.\nPara la transferencia debe utilizar Exportador XML para transformar los datos en archivo XML, y luego subir ese archivo."; + $lang->about_importer = "Es posible trasferir los datos de Zeroboard4, zb5beta o de otros programas a ZeroBoardXE.\nPara la transferencia debe utilizar XML Exporter para transformar los datos en archivo XML, y luego subir ese archivo."; $lang->about_target_path = "Para descargar los archivos adjuntos de ZeroBoard4, ingresa la ubicación de ZeroBoard4 instalado.\nSi esta en el mismo servidor escriba la ubicación de ZeroBoard4 como por ejemplo: /home/ID/public_html/bbs o si esta en otro servidor escriba la ubicación de ZeroBoard4 instalado como por ejemplo: http://dominio/bbs"; ?> diff --git a/modules/importer/lang/fr.lang.php b/modules/importer/lang/fr.lang.php index 01a273127..87af14ed9 100644 --- a/modules/importer/lang/fr.lang.php +++ b/modules/importer/lang/fr.lang.php @@ -8,6 +8,7 @@ // words for button $lang->cmd_sync_member = 'Synchroniser'; $lang->cmd_continue = 'Continuer'; + $lang->preprocessing = '데이터 이전을 위한 사전 준비중입니다.'; // items $lang->importer = 'Transférer des Données du Zeroboard'; @@ -51,7 +52,7 @@ $lang->about_ttxml_user_id = 'Please input user ID to set as author on transfering TTXML. (user ID must be already signed up)'; $lang->about_type_module = 'If you are transfering the board or articles information, select this option'; $lang->about_type_syncmember = 'If you are trying to synchronize the member information after transfering member and article information, select this option'; - $lang->about_importer = "You can transfer Zeroboard4, Zeroboard5 Beta or other program's data into ZeroboardXE's data.\nIn order to tranfer, you have to use XML Exporter to convert the data you want into XML File then upload it."; + $lang->about_importer = "You can transfer Zeroboard4, Zeroboard5 Beta or other program's data into ZeroboardXE's data.\nIn order to tranfer, you have to use XML Exporter to convert the data you want into XML File then upload it."; $lang->about_target_path = "To get attachments from Zeroboard4, please input the address where Zeroboard4 is installed.\nIf it is located in the same server, input Zeroboard4's path such as /home/USERID/public_html/bbs\nIf it is not located in the same server, input the address where Zeroboard4 is installed. ex. http://Domain/bbs"; ?> diff --git a/modules/importer/lang/jp.lang.php b/modules/importer/lang/jp.lang.php index a390d8129..d920f31f1 100644 --- a/modules/importer/lang/jp.lang.php +++ b/modules/importer/lang/jp.lang.php @@ -8,6 +8,7 @@ // ボタンに使用する用語 $lang->cmd_sync_member = '同期化'; $lang->cmd_continue = '続ける'; + $lang->preprocessing = '데이터 이전을 위한 사전 준비중입니다.'; // 項目 $lang->importer = 'ZBデータ変換'; @@ -51,7 +52,7 @@ $lang->about_ttxml_user_id = 'TTXML移転時に投稿者として指定するユーザIDを入力してください(すでに加入されているIDでなければなりません)。'; $lang->about_type_module = 'データ変換の対象が書き込みデータである場合は選択してください。'; $lang->about_type_syncmember = '会員情報と書き込みデータなどの変換を行った後、会員情報を同期化する必要がある場合は、選択してください。'; - $lang->about_importer = "ゼロボード4、zb5betaまたは他のプログラムの書き込みデータをゼロボードXEのデータに変換することができます。\n変換するためには、XML Exporterを利用して変換したい書き込みデータをXMLファイルで作成してアップロードしてください。"; + $lang->about_importer = "ゼロボード4、zb5betaまたは他のプログラムの書き込みデータをゼロボードXEのデータに変換することができます。\n変換するためには、XML Exporterを利用して変換したい書き込みデータをXMLファイルで作成してアップロードしてください。"; $lang->about_target_path = "添付ファイルをダウンロードするためには、ゼロボード4がインストールされた場所を入力してください。同じサーバ上にある場合は「/home/ID/public_html/bbs」のように入力し、他のサーバにある場合は、「http://ドメイン/bbs」のようにゼロボードがインストールされているURLを入力してください。"; ?> diff --git a/modules/importer/lang/ko.lang.php b/modules/importer/lang/ko.lang.php index 95e9e5224..21e54f2ad 100644 --- a/modules/importer/lang/ko.lang.php +++ b/modules/importer/lang/ko.lang.php @@ -8,6 +8,7 @@ // 버튼에 사용되는 언어 $lang->cmd_sync_member = '동기화'; $lang->cmd_continue = '계속진행'; + $lang->preprocessing = '데이터 이전을 위한 사전 준비중입니다.'; // 항목 $lang->importer = '제로보드 데이터 이전'; @@ -26,6 +27,7 @@ 13 => 'Step 1-3. 대상 분류 선택', 2 => 'Step 2. XML파일 지정', 3 => 'Step 2. 회원정보와 게시물의 정보 동기화', + 99 => '데이터 이전', ); $lang->import_step_desc = array( @@ -34,6 +36,7 @@ 13 => '데이터 이전을 할 대상 분류를 선택해주세요.', 2 => "데이터 이전을 할 XML파일의 경로를 입력해주세요.\n상대 또는 절대 경로를 입력하시면 됩니다", 3 => '회원정보와 게시물의 정보가 이전후에 맞지 않을 수 있습니다. 이 때 동기화를 하시면 user_id를 기반으로 올바르게 동작하도록 합니다.', + 99 => '데이터를 이전중입니다', ); // 안내/경고 @@ -51,6 +54,6 @@ $lang->about_ttxml_user_id = 'TTXML이전시에 글쓴이로 지정할 사용자 아이디를 입력해주세요. (이미 가입된 아이디여야 합니다)'; $lang->about_type_module = '데이터 이전 대상이 게시판등의 게시물 정보일 경우 선택해주세요'; $lang->about_type_syncmember = '회원정보와 게시물정보등을 이전후 회원정보 동기화 해야 할때 선택해주세요'; - $lang->about_importer = "제로보드4, zb5beta 또는 다른 프로그램의 데이터를 제로보드XE 데이터로 이전할 수 있습니다.\n이전을 위해서는 XML Exporter를 이용해서 원하는 데이터를 XML파일로 생성후 업로드해주셔야 합니다."; + $lang->about_importer = "제로보드4, zb5beta 또는 다른 프로그램의 데이터를 제로보드XE 데이터로 이전할 수 있습니다.\n이전을 위해서는 XML Exporter를 이용해서 원하는 데이터를 XML파일로 생성후 업로드해주셔야 합니다."; $lang->about_target_path = "첨부파일을 받기 위해 제로보드4가 설치된 위치를 입력해주세요.\n같은 서버에 있을 경우 /home/아이디/public_html/bbs 등과 같이 제로보드4의 위치를 입력하시고\n다른 서버일 경우 http://도메인/bbs 처럼 제로보드가 설치된 곳의 url을 입력해주세요"; ?> diff --git a/modules/importer/lang/ru.lang.php b/modules/importer/lang/ru.lang.php index a5f5d3f71..f47810488 100644 --- a/modules/importer/lang/ru.lang.php +++ b/modules/importer/lang/ru.lang.php @@ -8,6 +8,7 @@ // слова для кнопок $lang->cmd_sync_member = 'Синхронизировать'; $lang->cmd_continue = 'Продолжить'; + $lang->preprocessing = '데이터 이전을 위한 사전 준비중입니다.'; // объекты $lang->importer = 'Импортировать данные zeroboard'; @@ -51,7 +52,7 @@ $lang->about_ttxml_user_id = 'TTXML이전시에 글쓴이로 지정할 사용자 아이디를 입력해주세요. (이미 가입된 아이디여야 합니다)'; $lang->about_type_module = 'Если Вы импортируете информацию форума или статей, выберите эту опцию'; $lang->about_type_syncmember = 'Если Вы пытаетесь синхронизировать информацию пользователей после импорта информации пользователей и статей, выберите эту опцию'; - $lang->about_importer = "Вы можете импортировать данные Zeroboard4, Zeroboard5 Beta или других программ в ZeroboardXE.\nЧтобы импортировать, Вам следует использовать XML Экспортер (XML Exporter), чтобы конвертировать нужные данные в XML Файл и затем загрузить его."; + $lang->about_importer = "Вы можете импортировать данные Zeroboard4, Zeroboard5 Beta или других программ в ZeroboardXE.\nЧтобы импортировать, Вам следует использовать XML Экспортер (XML Exporter), чтобы конвертировать нужные данные в XML Файл и затем загрузить его."; $lang->about_target_path = "Чтобы получить вложения с Zeroboard4, пожалуйста, введите адрес, где установлена Zeroboard4.\nЕсли она раположена на том же сервере, введите путь к Zeroboard4 как /home/USERID/public_html/bbs\nЕсли нет, введите адрес, где Zeroboard4 установлена. Например: http://Domain/bbs"; ?> diff --git a/modules/importer/lang/zh-CN.lang.php b/modules/importer/lang/zh-CN.lang.php index 85f772324..137b31008 100644 --- a/modules/importer/lang/zh-CN.lang.php +++ b/modules/importer/lang/zh-CN.lang.php @@ -8,6 +8,7 @@ // 按钮上使用的语言 $lang->cmd_sync_member = '同步'; $lang->cmd_continue = '继续进行'; + $lang->preprocessing = '데이터 이전을 위한 사전 준비중입니다.'; // 项目 $lang->importer = '数据导入'; @@ -51,7 +52,7 @@ $lang->about_ttxml_user_id = '请输入导入TTXML数据时指定为主题发布者的ID(必须是已注册会员)。'; $lang->about_type_module = '数据导入对象为版面主题时请选择此项。'; $lang->about_type_syncmember = '导入会员信息和文章信息后需要同步会员信息时请选择此项。'; - $lang->about_importer = "不仅可以导入Zeroboard 4,Zb5beta的数据,也可以把其他程序数据导入到Zeroboard XE当中。\n导入数据时请利用 XML Exporter生成XML文件后再上传。"; + $lang->about_importer = "不仅可以导入Zeroboard 4,Zb5beta的数据,也可以把其他程序数据导入到Zeroboard XE当中。\n导入数据时请利用 XML Exporter生成XML文件后再上传。"; $lang->about_target_path = "为了下载附件请输入Zeroboard 4的安装位置。\n位置在同一个服务器时,请输入如 /home/id/public_html/bbs的路径,在不同服务器时,请输入如 http://域名/bbs的url地址。"; ?> diff --git a/modules/importer/tpl/css/importer.css b/modules/importer/tpl/css/importer.css index cdd6e64a7..6362bd0d7 100644 --- a/modules/importer/tpl/css/importer.css +++ b/modules/importer/tpl/css/importer.css @@ -1,3 +1,9 @@ @charset "utf-8"; #step2_position { height:150px; overflow-y:scroll; border:2px solid #DDDDDD; } + +div.progressBox { width:700px; margin:30px auto; border:1px solid #DDDDDD; white-space:nowrap; overflow:hidden; height:20px;} +div.progress1 { float:left; border-right:1px solid #DDDDDD; text-align:right; overflow:hidden; background-color:#361DB5; color:#FFFFFF; font-family:tahoma; font-family:tahoma; font-size:9pt; white-space:nowrap; height:20px;} +div.progress2 { float:left; text-align:left; overflow:hidden; white-space:nowrap; color:#444444; font-family:tahoma; font-size:9pt; height:20px;} + +.w700 { width:700px; } diff --git a/modules/importer/tpl/header.html b/modules/importer/tpl/header.html new file mode 100644 index 000000000..f71cc75c2 --- /dev/null +++ b/modules/importer/tpl/header.html @@ -0,0 +1,18 @@ + + + +{@ $type_list = array('module'=>$lang->type_module, 'ttxml'=>$lang->type_ttxml, 'member'=>$lang->type_member, 'sync'=>$lang->type_syncmember, 'message'=>$lang->type_message) } + +

{$lang->importer} {$lang->cmd_management}

+ + +
{nl2br($lang->about_importer)}
+ +
+ +
+ diff --git a/modules/importer/tpl/index.html b/modules/importer/tpl/index.html index c92a0a3ec..9e507c8b2 100644 --- a/modules/importer/tpl/index.html +++ b/modules/importer/tpl/index.html @@ -16,25 +16,25 @@ {$lang->import_step_title[1]} - {$lang->import_step_desc[1]} - + - - - - - - - - - + - + + + + + + + + + diff --git a/modules/importer/tpl/js/importer_admin.js b/modules/importer/tpl/js/importer_admin.js index 3da6d22c5..3e8d7c591 100644 --- a/modules/importer/tpl/js/importer_admin.js +++ b/modules/importer/tpl/js/importer_admin.js @@ -3,7 +3,10 @@ * @author zero (zero@nzeo.com) * @brief importer에서 사용하는 javascript **/ -/* 회원정보와 게시물의 싱크 */ + +/** + * 회원정보와 게시글/댓글등의 동기화 요청 및 결과 처리 함수 + **/ function doSync(fo_obj) { exec_xml('importer','procImporterAdminSync', new Array(), completeSync); return false; @@ -15,203 +18,144 @@ function completeSync(ret_obj) { } -/* 회원정보 데이터 import */ -function doImportMember(fo_obj) { +/** + * xml파일을 DB입력전에 extract를 통해 분할 캐싱을 요청하는 함수 + **/ +var prepared = false; +function doPreProcessing(fo_obj) { var xml_file = fo_obj.xml_file.value; if(!xml_file) return false; + var type = fo_obj.type.value; + + xDisplay('importForm','none'); + xDisplay('process','block'); + xInnerHtml('status',''); + setTimeout(doPrepareDot, 50); + var params = new Array(); params['xml_file'] = xml_file; - params['total_count'] = fo_obj.total_count.value; - params['success_count'] = fo_obj.success_count.value; - params['readed_line'] = fo_obj.readed_line.value; + params['type'] = type; - var response_tags = new Array("error","message", "total_count", "success_count", "readed_line", "is_finished"); - - exec_xml('importer','procImporterAdminMemberImport', params, completeImportMember, response_tags); + var response_tags = new Array('error','message','type','total','cur','key','status'); + exec_xml('importer','procImporterAdminPreProcessing', params, completePreProcessing, response_tags); return false; } -function completeImportMember(ret_obj) { - var total_count = ret_obj['total_count']; - var success_count = ret_obj['success_count']; - var readed_line = ret_obj['readed_line']; - var is_finished = ret_obj['is_finished']; +/* 준비중일때 .(dot) 찍어주는.. */ +function doPrepareDot() { + if(prepared) return; - if(is_finished == '1') { - var fo_obj = xGetElementById("fo_import"); - fo_obj.total_count.value = 0; - fo_obj.success_count.value = 0; - fo_obj.readed_line.value = 0; - fo_obj.xml_file.disabled = false; - xGetElementById("status").style.display = "none"; - xGetElementById("status_button_prev").style.display = "block"; - xGetElementById("status_button").style.display = "none"; - - - xInnerHtml("status", ret_obj['message']); - alert(ret_obj['message']); - } else { - var fo_obj = xGetElementById("fo_import"); - fo_obj.total_count.value = total_count; - fo_obj.success_count.value = success_count; - fo_obj.readed_line.value = readed_line; - fo_obj.xml_file.disabled = true; - xGetElementById("status").style.display = "block"; - xGetElementById("status_button_prev").style.display = "none"; - xGetElementById("status_button").style.display = "block"; - xInnerHtml("status", ret_obj['message']); - - doImportMember(fo_obj); - } + var str = xInnerHtml('status'); + if(str.length<1 || str.length - preProcessingMsg.length > 50) str = preProcessingMsg; + else str += "."; + xInnerHtml('status', str); + setTimeout(doPrepareDot, 50); } -/* 쪽지 데이터 import */ -function doImportMessage(fo_obj) { - var xml_file = fo_obj.xml_file.value; - if(!xml_file) return false; +/* 준비가 끝났을때 호출되는 함수 */ +function completePreProcessing(ret_obj, response_tags) { + prepared = true; + xInnerHtml('status',''); + + var status = ret_obj['status']; + var message = ret_obj['message']; + var type = ret_obj['type']; + var total = parseInt(ret_obj['total'],10); + var cur = parseInt(ret_obj['cur'],10); + var key = ret_obj['key']; + + if(status == -1) { + xDisplay('importForm','block'); + xDisplay('process','none'); + xDisplay('btn_reload','block'); + xDisplay('btn_continue','none'); + alert(message); + return; + } + + xDisplay('btn_reload','none'); + xDisplay('btn_continue','block'); + + var fo_obj = xGetElementById('fo_process'); + fo_obj.type.value = type; + fo_obj.total.value = total; + fo_obj.cur.value = cur; + fo_obj.key.value = key; + + var fo_import = xGetElementById('fo_import'); + if(fo_import && fo_import.target_module) fo_obj.target_module.value = fo_import.target_module.options[fo_import.target_module.selectedIndex].value; + if(fo_import && fo_import.user_id) fo_obj.user_id.value = fo_import.user_id.value; + + fo_obj.unit_count.value = fo_import.unit_count.options[fo_import.unit_count.selectedIndex].value; + + // extract된 파일을 이용해서 import + doImport(); +} + +/* @brief 임포트 시작 */ +function doImport() { + var fo_obj = xGetElementById('fo_process'); var params = new Array(); - params['xml_file'] = xml_file; - params['total_count'] = fo_obj.total_count.value; - params['success_count'] = fo_obj.success_count.value; - params['readed_line'] = fo_obj.readed_line.value; - - var response_tags = new Array("error","message", "total_count", "success_count", "readed_line", "is_finished"); - - exec_xml('importer','procImporterAdminMessageImport', params, completeImportMessage, response_tags); - - return false; -} - -function completeImportMessage(ret_obj) { - var total_count = ret_obj['total_count']; - var success_count = ret_obj['success_count']; - var readed_line = ret_obj['readed_line']; - var is_finished = ret_obj['is_finished']; - - if(is_finished == '1') { - var fo_obj = xGetElementById("fo_import"); - fo_obj.total_count.value = 0; - fo_obj.success_count.value = 0; - fo_obj.readed_line.value = 0; - fo_obj.xml_file.disabled = false; - xGetElementById("status").style.display = "none"; - xGetElementById("status_button_prev").style.display = "block"; - xGetElementById("status_button").style.display = "none"; - - - xInnerHtml("status", ret_obj['message']); - alert(ret_obj['message']); - } else { - var fo_obj = xGetElementById("fo_import"); - fo_obj.total_count.value = total_count; - fo_obj.success_count.value = success_count; - fo_obj.readed_line.value = readed_line; - fo_obj.xml_file.disabled = true; - xGetElementById("status").style.display = "block"; - xGetElementById("status_button_prev").style.display = "none"; - xGetElementById("status_button").style.display = "block"; - xInnerHtml("status", ret_obj['message']); - - doImportMessage(fo_obj); - } -} - -/* 모듈 데이터 import */ -function doImportModule(fo_obj) { - var target_module = fo_obj.target_module.options[fo_obj.target_module.selectedIndex].value; - if(!target_module) return false; - - var xml_file = fo_obj.xml_file.value; - if(!xml_file) return false; - - var params = new Array(); - params['xml_file'] = xml_file; - params['target_module'] = target_module; - params['total_count'] = fo_obj.total_count.value; - params['success_count'] = fo_obj.success_count.value; - params['readed_line'] = fo_obj.readed_line.value; - - var response_tags = new Array("error","message", "total_count", "success_count", "readed_line", "is_finished"); - - exec_xml('importer','procImporterAdminModuleImport', params, completeImportModule, response_tags); - - return false; -} - -function completeImportModule(ret_obj, response_tags) { - var total_count = ret_obj['total_count']; - var success_count = ret_obj['success_count']; - var readed_line = ret_obj['readed_line']; - var is_finished = ret_obj['is_finished']; - - if(is_finished == '1') { - var fo_obj = xGetElementById("fo_import"); - fo_obj.target_module.disabled = false; - fo_obj.xml_file.disabled = false; - fo_obj.total_count.value = 0; - fo_obj.success_count.value = 0; - fo_obj.readed_line.value = 0; - - xGetElementById("status").style.display = "none"; - xGetElementById("status_button_prev").style.display = "block"; - xGetElementById("status_button").style.display = "none"; - - - xInnerHtml("status", ret_obj['message']); - - alert(ret_obj['message']); - } else { - var fo_obj = xGetElementById("fo_import"); - fo_obj.target_module.disabled = true; - fo_obj.xml_file.disabled = true; - fo_obj.total_count.value = total_count; - fo_obj.success_count.value = success_count; - fo_obj.readed_line.value = readed_line; - - xGetElementById("status").style.display = "block"; - xGetElementById("status_button_prev").style.display = "none"; - xGetElementById("status_button").style.display = "block"; - - xInnerHtml("status", ret_obj['message']); - - doImportModule(fo_obj); - } -} - -/* TTXML 데이터 import */ -function doImportTTXML(fo_obj) { - var target_module = fo_obj.target_module.options[fo_obj.target_module.selectedIndex].value; - if(!target_module) return false; - - var xml_file = fo_obj.xml_file.value; - if(!xml_file) return false; - - var params = new Array(); - params['xml_file'] = xml_file; - params['target_module'] = target_module; - params['total_count'] = fo_obj.total_count.value; - params['success_count'] = fo_obj.success_count.value; - params['readed_line'] = fo_obj.readed_line.value; + params['type'] = fo_obj.type.value; + params['total'] = fo_obj.total.value; + params['cur'] = fo_obj.cur.value; + params['key'] = fo_obj.key.value; + params['target_module'] = fo_obj.target_module.value; + params['unit_count'] = fo_obj.unit_count.value; params['user_id'] = fo_obj.user_id.value; - var response_tags = new Array("error","message", "total_count", "success_count", "readed_line", "is_finished"); + displayProgress(params['total'], params['cur']); - exec_xml('importer','procImporterAdminTTXMLImport', params, completeImportTTXML, response_tags); + var response_tags = new Array('error','message','type','total','cur','key'); + + show_waiting_message = false; + exec_xml('importer','procImporterAdminImport', params, completeImport, response_tags); + show_waiting_message = true; return false; } -function completeImportTTXML(ret_obj, response_tags) { - var total_count = ret_obj['total_count']; - var success_count = ret_obj['success_count']; - var readed_line = ret_obj['readed_line']; - var is_finished = ret_obj['is_finished']; - xGetElementById("status").style.display = 'block'; - xInnerHtml("status", ret_obj['message']); +/* import중 표시 */ +function completeImport(ret_obj, response_tags) { + var message = ret_obj['message']; + var type = ret_obj['type']; + var total = parseInt(ret_obj['total'],10); + var cur = parseInt(ret_obj['cur'],10); + var key = ret_obj['key']; - alert(ret_obj['message']); + displayProgress(total, cur); + + var fo_obj = xGetElementById('fo_process'); + fo_obj.type.value = type; + fo_obj.total.value = total; + fo_obj.cur.value = cur; + fo_obj.key.value = key; + + // extract된 파일을 이용해서 import + if(total>cur) doImport(); + else { + alert(message); + fo_obj.reset(); + xDisplay('process','none'); + xDisplay('importForm','block'); + xGetElementById('fo_import').reset(); + } +} + +/* 상태 표시 함수 */ +function displayProgress(total, cur) { + // 진행률 구함 + var per = 0; + if(total > 0) per = Math.round(cur/total*100); + else per = 100; + if(!per) per = 1; + + var status = '
'+per+'% 
'; + status += '
'+cur+'/'+total+'
'; + status += '
'; + xInnerHtml('status', status); } diff --git a/modules/importer/tpl/member.html b/modules/importer/tpl/member.html index f844605ad..0995a9480 100644 --- a/modules/importer/tpl/member.html +++ b/modules/importer/tpl/member.html @@ -1,33 +1,34 @@ - - + -

{$lang->importer} {$lang->cmd_management}

- -
{nl2br($lang->about_importer)}
- -
-
- - - +
+ +
{$lang->import_step_title[2]} - {$lang->import_step_desc[2]}
- +

ex1) ../member.xml

ex2) http://...../member.xml

-
- + +
- -
+ + diff --git a/modules/importer/tpl/message.html b/modules/importer/tpl/message.html index 928860723..a8174ab5e 100644 --- a/modules/importer/tpl/message.html +++ b/modules/importer/tpl/message.html @@ -1,33 +1,34 @@ - - + -

{$lang->importer} {$lang->cmd_management}

- -
{nl2br($lang->about_importer)}
- -
-
- - - +
+ +
{$lang->import_step_title[2]} - {$lang->import_step_desc[2]}
- +

ex1) ../message.xml

ex2) http://...../message.xml

-
- + +
- -
+ + diff --git a/modules/importer/tpl/module.html b/modules/importer/tpl/module.html index 097930a02..7cb5e6c58 100644 --- a/modules/importer/tpl/module.html +++ b/modules/importer/tpl/module.html @@ -1,23 +1,15 @@ - - - -

{$lang->importer} {$lang->cmd_management}

- - -
{nl2br($lang->about_importer)}
+ -
-
- - - +
+ +
{$lang->import_step_title[1]} - {$lang->import_step_desc[12]}
- @@ -31,21 +23,31 @@
{$lang->import_step_title[2]} - {$lang->import_step_desc[2]}
- +

ex1) ../module.xml

ex2) http://...../module.xml

-
- + +
- -
+ diff --git a/modules/importer/tpl/process.html b/modules/importer/tpl/process.html new file mode 100644 index 000000000..3f080939d --- /dev/null +++ b/modules/importer/tpl/process.html @@ -0,0 +1,30 @@ + + + diff --git a/modules/importer/tpl/sync.html b/modules/importer/tpl/sync.html index 6068c5b91..d493ef23a 100644 --- a/modules/importer/tpl/sync.html +++ b/modules/importer/tpl/sync.html @@ -1,16 +1,10 @@ - - + -

{$lang->importer} {$lang->cmd_management}

- - -
{nl2br($lang->about_importer)}
- -
- - - - - -
{$lang->import_step_title[3]} - {$lang->import_step_desc[3]}
-
+
+ + + + + +
{$lang->import_step_title[3]} - {$lang->import_step_desc[3]}
+
diff --git a/modules/importer/tpl/ttxml.html b/modules/importer/tpl/ttxml.html index 8ee123b82..9429b9b7e 100644 --- a/modules/importer/tpl/ttxml.html +++ b/modules/importer/tpl/ttxml.html @@ -1,17 +1,9 @@ - - - -

{$lang->importer} {$lang->cmd_management}

- - -
{nl2br($lang->about_importer)}
+ -
-
- - - +
+ + @@ -40,21 +32,30 @@
{$lang->import_step_title[1]} - {$lang->import_step_desc[12]}{$lang->import_step_title[2]} - {$lang->import_step_desc[2]}
- +

ex1) ../module.xml

ex2) http://...../module.xml

-
- + +
- - -
+ diff --git a/modules/importer/ttimport.class.php b/modules/importer/ttimport.class.php new file mode 100644 index 000000000..fa7f52d4f --- /dev/null +++ b/modules/importer/ttimport.class.php @@ -0,0 +1,413 @@ +oXmlParser = new XmlParser(); + + // 타겟 모듈의 카테고리 정보 구함 + $oDocumentModel = &getModel('document'); + $category_list = $category_titles = array(); + $category_list = $oDocumentModel->getCategoryList($module_srl); + if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; + + // 먼저 카테고리 정보를 입력함 + $category_file = preg_replace('/index$/i', 'category', $index_file); + if(file_exists($category_file)) { + $buff = FileHandler::readFile($category_file); + + // xmlParser객체 생성 + $xmlDoc = $this->oXmlParser->loadXmlFile($category_file); + + $categories = $xmlDoc->items->category; + if($categories) { + if(!is_array($categories)) $categories = array($categories); + $oDocumentController = &getController('document'); + foreach($categories as $k => $v) { + $category = $v->name->body; + if(!$category || $category_titles[$category]) continue; + + $obj = null; + $obj->title = $category; + $obj->module_srl = $module_srl; + $output = $oDocumentController->insertCategory($obj); + } + $oDocumentController = &getController('document'); + $oDocumentController->makeCategoryFile($module_srl); + } + @unlink($category_file); + } + + $category_list = $category_titles = array(); + $category_list = $oDocumentModel->getCategoryList($module_srl); + if(count($category_list)) foreach($category_list as $key => $val) $category_titles[$val->title] = $val->category_srl; + + // 관리자 정보를 구함 + $oMemberModel = &getModel('member'); + $member_info = $oMemberModel->getMemberInfoByUserID($user_id); + + if(!$cur) $cur = 0; + + // index파일을 염 + $f = fopen($index_file,"r"); + + // 이미 읽혀진 것은 패스 + for($i=0;$i<$cur;$i++) fgets($f, 1024); + + // 라인단위로 읽어들이면서 $cur보다 커지고 $cur+$unit_count개보다 작으면 중지 + for($idx=$cur;$idx<$cur+$unit_count;$idx++) { + if(feof($f)) break; + + // 정해진 위치를 찾음 + $target_file = trim(fgets($f, 1024)); + + if(!file_exists($target_file)) continue; + + // 이제부터 데이터를 가져오면서 처리 + $fp = fopen($target_file,"r"); + if(!$fp) continue; + + $obj = null; + $obj->module_srl = $module_srl; + $obj->document_srl = getNextSequence(); + $obj->uploaded_count = 0; + + $files = array(); + + $started = false; + $buff = null; + + // 본문 데이터부터 처리 시작 + while(!feof($fp)) { + $str = fgets($fp, 1024); + + // 한 아이템 준비 시작 + if(substr($str,0,5) == 'importAttaches($fp, $module_srl, $obj->document_srl, $files, $str)) $obj->uploaded_count++; + continue; + } + + if($started) $buff .= $str; + } + + $xmlDoc = $this->oXmlParser->parse(''.$buff); + + $category = $xmlDoc->post->category->body; + if($category_titles[$category]) $obj->category_srl = $category_titles[$category]; + + $obj->is_notice = 'N'; + $obj->is_secret = $xmlDoc->post->visibility->body=='syndicated'?'N':'Y'; + $obj->title = $xmlDoc->post->title->body; + $obj->content = $xmlDoc->post->content->body; + $obj->password = md5($xmlDoc->post->password->body); + //$obj->allow_comment = $xmlDoc->post->acceptComment->body==1?'Y':'N'; + $obj->allow_comment = 'Y'; + //$obj->allow_trackback = $xmlDoc->post->acceptTrackback->body==1?'Y':'N'; + $obj->allow_trackback = 'Y'; + $obj->regdate = date("YmdHis",$xmlDoc->post->published->body); + $obj->last_update = date("YmdHis", $xmlDoc->post->modified->body); + if(!$obj->last_update) $obj->last_update = $obj->regdate; + + $tag = null; + $tmp_tags = null; + $tag = $xmlDoc->post->tag; + if($tag) { + if(!is_array($tag)) $tag = array($tag); + foreach($tag as $key => $val) $tmp_tags[] = $val->body; + $obj->tags = implode(',',$tmp_tags); + } + + $obj->readed_count = 0; + $obj->voted_count = 0; + $obj->nick_name = $member_info->nick_name; + $obj->user_name = $member_info->user_name; + $obj->user_id = $member_info->user_id; + $obj->member_srl = $member_info->member_srl; + $obj->email_address = $member_info->email_address; + $obj->homepage = $member_info->homepage; + $obj->ipaddress = $_REMOTE['SERVER_ADDR']; + $obj->list_order = $obj->update_order = $obj->document_srl*-1; + $obj->lock_comment = 'N'; + $obj->notify_message = 'N'; + + // content 정보 변경 (첨부파일) + $obj->content = str_replace('[##_ATTACH_PATH_##]/','',$obj->content); + if(count($files)) { + foreach($files as $label => $filename) { + $obj->content = preg_replace_callback('!\[##_([a-z0-9]+)\|([^\|]*)\|([^\|]*)\|(.*?)_##\]!is', array($this, '_replaceTTImgTag'), $obj->content); + } + } + if(count($files)) { + foreach($files as $key => $val) { + $obj->content = preg_replace('/(src|href)\=(["\']?)'.preg_quote($key).'(["\']?)/i','$1="'.$val.'"',$obj->content); + } + } + + // 역인글 입력 + $obj->trackback_count = 0; + if($xmlDoc->post->trackback) { + $trackbacks = $xmlDoc->post->trackback; + if(!is_array($trackbacks)) $trackbacks = array($trackbacks); + if(count($trackbacks)) { + foreach($trackbacks as $key => $val) { + $tobj = null; + $tobj->trackback_srl = getNextSequence(); + $tobj->module_srl = $module_srl; + $tobj->document_srl = $obj->document_srl; + $tobj->url = $val->url->body; + $tobj->title = $val->title->body; + $tobj->blog_name = $val->site->body; + $tobj->excerpt = $val->excerpt->body; + $tobj->regdate = date("YmdHis",$val->received->body); + $tobj->ipaddress = $val->ip->body; + $tobj->list_order = -1*$tobj->trackback_srl; + $output = executeQuery('trackback.insertTrackback', $tobj); + if($output->toBool()) $obj->trackback_count++; + } + } + } + + // 댓글입력 + $obj->comment_count = 0; + if($xmlDoc->post->comment) { + $comment = $xmlDoc->post->comment; + if(!is_array($comment)) $comment = array($comment); + foreach($comment as $key => $val) { + $parent_srl = $this->insertComment($val, $module_srl, $obj->document_srl, 0); + if($parent_srl === false) continue; + + $obj->comment_count++; + if($val->comment) { + $child_comment = $val->comment; + if(!is_array($child_comment)) $child_comment = array($child_comment); + foreach($child_comment as $k => $v) { + $result = $this->insertComment($v, $module_srl, $obj->document_srl, $parent_srl); + if($result !== false) $obj->comment_count++; + } + } + } + } + + // 문서 입력 + $output = executeQuery('document.insertDocument', $obj); + + if($output->toBool()) { + // 태그 입력 + if($obj->tags) { + $tag_list = explode(',',$obj->tags); + $tag_count = count($tag_list); + for($i=0;$i<$tag_count;$i++) { + $args = null; + $args->tag_srl = getNextSequence(); + $args->module_srl = $module_srl; + $args->document_srl = $obj->document_srl; + $args->tag = trim($tag_list[$i]); + $args->regdate = $obj->regdate; + if(!$args->tag) continue; + $output = executeQuery('tag.insertTag', $args); + } + } + } + + fclose($fp); + @unlink($target_file); + } + + fclose($f); + + return $idx-1; + } + + /** + * @brief 첨부파일 정리 + **/ + function importAttaches($fp, $module_srl, $upload_target_srl, &$files, $buff) { + $uploaded_count = 0; + + $file_obj = null; + $file_obj->file_srl = getNextSequence(); + $file_obj->upload_target_srl = $upload_target_srl; + $file_obj->module_srl = $module_srl; + + while(!feof($fp)) { + $str = fgets($fp, 1024); + + // 로 끝나면 중단 + if(trim($str) == '') break; + + // 로 시작하면 xml파일내의 첨부파일로 처리 + if(substr($str, 0, 9)=='') { + $file_obj->file = $this->saveTemporaryFile($fp, $str); + continue; + } + + $buff .= $str; + } + + $buff .= ''; + + $xmlDoc = $this->oXmlParser->parse($buff); + + $file_obj->source_filename = $xmlDoc->attachment->name->body; + $file_obj->download_count = $xmlDoc->attachment->downloads->body; + $label = $xmlDoc->attachment->label->body; + + // 이미지인지 기타 파일인지 체크하여 upload path 지정 + if(preg_match("/\.(jpg|jpeg|gif|png|wmv|wma|mpg|mpeg|avi|swf|flv|mp3|asaf|wav|asx|midi|asf)$/i", $file_obj->source_filename)) { + $path = sprintf("./files/attach/images/%s/%s/", $module_srl,$upload_target_srl); + $filename = $path.$file_obj->source_filename; + $file_obj->direct_download = 'Y'; + } else { + $path = sprintf("./files/attach/binaries/%s/%s/", $module_srl, $upload_target_srl); + $filename = $path.md5(crypt(rand(1000000,900000), rand(0,100))); + $file_obj->direct_download = 'N'; + } + + // 디렉토리 생성 + if(!FileHandler::makeDir($path)) continue; + + @rename($file_obj->file, $filename); + + // DB입력 + unset($file_obj->file); + $file_obj->uploaded_filename = $filename; + $file_obj->file_size = filesize($filename); + $file_obj->comment = NULL; + $file_obj->member_srl = 0; + $file_obj->sid = md5(rand(rand(1111111,4444444),rand(4444445,9999999))); + $file_obj->isvalid = 'Y'; + $output = executeQuery('file.insertFile', $file_obj); + + if($output->toBool()) { + $uploaded_count++; + $tmp_obj = null; + $tmp_obj->source_filename = $file_obj->source_filename; + if($file_obj->direct_download == 'Y') $files[$file_obj->source_filename] = $file_obj->uploaded_filename; + else $files[$file_obj->source_filename] = getUrl('','module','file','act','procFileDownload','file_srl',$file_obj->file_srl,'sid',$file_obj->sid); + return true; + } + + return false; + } + + /** + * @biref 임의로 사용할 파일이름을 return + **/ + function getTmpFilename() { + $path = "./files/cache/tmp"; + if(!is_dir($path)) FileHandler::makeDir($path); + $filename = sprintf("%s/%d", $path, rand(11111111,99999999)); + if(file_exists($filename)) $filename .= rand(111,999); + return $filename; + } + + /** + * @brief 특정 파일포인트로부터 key에 해당하는 값이 나타날때까지 buff를 읽음 + **/ + function saveTemporaryFile($fp, $buff) { + $temp_filename = $this->getTmpFilename(); + $buff = substr($buff, 9); + + while(!feof($fp)) { + $str = trim(fgets($fp, 1024)); + $buff .= $str; + if(substr($str, -10) == '') break; + } + + $buff = substr($buff, 0, -10); + + $f = fopen($temp_filename, "w"); + fwrite($f, base64_decode($buff)); + fclose($f); + return $temp_filename; + } + + /** + * @brief ttxml의 자체 img 태그를 치환 + **/ + function _replaceTTImgTag($matches) { + return sprintf("\"%s\"

", $matches[2], str_replace("\"","\\\"",$matches[4])); + } + + /** + * @brief 댓글 입력 + **/ + function insertComment($val, $module_srl, $document_srl, $parent_srl = 0) { + $tobj = null; + $tobj->comment_srl = getNextSequence(); + $tobj->module_srl = $module_srl; + $tobj->document_srl = $document_srl; + $tobj->is_secret = $val->secret->body==1?'Y':'N'; + $tobj->notify_message = 'N'; + $tobj->content = nl2br($val->content->body); + $tobj->voted_count = 0; + $tobj->password = $val->password->body; + $tobj->nick_name = $val->commenter->name->body; + $tobj->member_srl = 0; + $tobj->homepage = $val->commenter->homepage->body; + $tobj->last_update = $tobj->regdate = date("YmdHis",$val->written->body); + $tobj->ipaddress = $val->commenter->ip->body; + $tobj->list_order = $tobj->comment_srl*-1; + $tobj->sequence = $sequence; + $tobj->parent_srl = $parent_srl; + + // 댓글 목록 부분을 먼저 입력 + $list_args = null; + $list_args->comment_srl = $tobj->comment_srl; + $list_args->document_srl = $tobj->document_srl; + $list_args->module_srl = $tobj->module_srl; + $list_args->regdate = $tobj->regdate; + + // 부모댓글이 없으면 바로 데이터를 설정 + if(!$tobj->parent_srl) { + $list_args->head = $list_args->arrange = $tobj->comment_srl; + $list_args->depth = 0; + + // 부모댓글이 있으면 부모글의 정보를 구해옴 + } else { + // 부모댓글의 정보를 구함 + $parent_args->comment_srl = $tobj->parent_srl; + $parent_output = executeQuery('comment.getCommentListItem', $parent_args); + + // 부모댓글이 존재하지 않으면 return + if(!$parent_output->toBool() || !$parent_output->data) continue; + $parent = $parent_output->data; + + $list_args->head = $parent->head; + $list_args->depth = $parent->depth+1; + if($list_args->depth<2) $list_args->arrange = $tobj->comment_srl; + else { + $list_args->arrange = $parent->arrange; + $output = executeQuery('comment.updateCommentListArrange', $list_args); + if(!$output->toBool()) return $output; + } + } + + $output = executeQuery('comment.insertCommentList', $list_args); + if($output->toBool()) { + $output = executeQuery('comment.insertComment', $tobj); + if($output->toBool()) return $tobj->comment_srl; + } + return false; + } + } +?> diff --git a/modules/member/member.admin.view.php b/modules/member/member.admin.view.php index 62ab4caf5..c4c22ed6a 100644 --- a/modules/member/member.admin.view.php +++ b/modules/member/member.admin.view.php @@ -44,8 +44,10 @@ $output = $oMemberAdminModel->getMemberList(); // 개인별로 그룹목록을 가져 옴 - foreach($output->data as $key => $member) { - $output->data[$key]->group_list = $oMemberModel->getMemberGroups($member->member_srl); + if($output->data) { + foreach($output->data as $key => $member) { + $output->data[$key]->group_list = $oMemberModel->getMemberGroups($member->member_srl); + } } // 템플릿에 쓰기 위해서 context::set