위젯 검출 정규 표현식을 수정

git-svn-id: http://xe-core.googlecode.com/svn/sandbox@2892 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
zero 2007-11-01 10:28:42 +00:00
parent f9896fe51a
commit 90aa62a6ac
993 changed files with 9190 additions and 10457 deletions

View file

@ -67,5 +67,42 @@
$this->setTemplateFile('comment_list');
}
/**
* @brief 관리자 페이지의 신고 목록 보기
**/
function dispCommentAdminDeclared() {
// 목록을 구하기 위한 옵션
$args->page = Context::get('page'); ///< 페이지
$args->list_count = 50; ///< 한페이지에 보여줄 글 수
$args->page_count = 10; ///< 페이지 네비게이션에 나타날 페이지의 수
$args->sort_index = 'comment_declared.declared_count'; ///< 소팅 값
$args->order_type = 'desc'; ///< 소팅 정렬 값
// 목록을 구함
$declared_output = executeQuery('comment.getDeclaredList', $args);
if($declared_output->data && count($declared_output->data)) {
$comment_list = array();
$oCommentModel = &getModel('comment');
foreach($declared_output->data as $key => $comment) {
$comment_list[$key] = new commentItem();
$comment_list[$key]->setAttribute($comment);
}
$declared_output->data = $comment_list;
}
// 템플릿에 쓰기 위해서 comment_model::getCommentList() 의 return object에 있는 값들을 세팅
Context::set('total_count', $declared_output->total_count);
Context::set('total_page', $declared_output->total_page);
Context::set('page', $declared_output->page);
Context::set('comment_list', $declared_output->data);
Context::set('page_navigation', $declared_output->page_navigation);
// 템플릿 지정
$this->setTemplatePath($this->module_path.'tpl');
$this->setTemplateFile('declared_list');
}
}
?>

View file

@ -5,6 +5,8 @@
* @brief comment 모듈의 high class
**/
require_once('./modules/comment/comment.item.php');
class comment extends ModuleObject {
/**
@ -14,6 +16,13 @@
// action forward에 등록 (관리자 모드에서 사용하기 위함)
$oModuleController = &getController('module');
$oModuleController->insertActionForward('comment', 'view', 'dispCommentAdminList');
$oModuleController->insertActionForward('comment', 'view', 'dispCommentAdminDeclared');
// 2007. 10. 17 게시글이 삭제될때 댓글도 삭제되도록 trigger 등록
$oModuleController->insertTrigger('document.deleteDocument', 'comment', 'controller', 'triggerDeleteDocumentComments', 'after');
// 2007. 10. 17 모듈이 삭제될때 등록된 댓글도 모두 삭제하는 트리거 추가
$oModuleController->insertTrigger('module.deleteModule', 'comment', 'controller', 'triggerDeleteModuleComments', 'after');
return new Object();
}
@ -22,6 +31,21 @@
* @brief 설치가 이상이 없는지 체크하는 method
**/
function checkUpdate() {
$oDB = &DB::getInstance();
$oModuleModel = &getModel('module');
// 2007. 10. 17 게시글이 삭제될때 댓글도 삭제되도록 trigger 등록
if(!$oModuleModel->getTrigger('document.deleteDocument', 'comment', 'controller', 'triggerDeleteDocumentComments', 'after')) return true;
// 2007. 10. 17 모듈이 삭제될때 등록된 댓글도 모두 삭제하는 트리거 추가
if(!$oModuleModel->getTrigger('module.deleteModule', 'comment', 'controller', 'triggerDeleteModuleComments', 'after')) return true;
// 2007. 10. 23 댓글에도 추천/ 알림 기능을 위한 컬럼 추가
if(!$oDB->isColumnExists("comments","voted_count")) return true;
if(!$oDB->isColumnExists("comments","notify_message")) return true;
if(!$oModuleModel->getActionForward('dispCommentAdminDeclared')) return true;
return false;
}
@ -29,7 +53,32 @@
* @brief 업데이트 실행
**/
function moduleUpdate() {
return new Object();
$oDB = &DB::getInstance();
$oModuleModel = &getModel('module');
$oModuleController = &getController('module');
// 2007. 10. 17 게시글이 삭제될때 댓글도 삭제되도록 trigger 등록
if(!$oModuleModel->getTrigger('document.deleteDocument', 'comment', 'controller', 'triggerDeleteDocumentComments', 'after'))
$oModuleController->insertTrigger('document.deleteDocument', 'comment', 'controller', 'triggerDeleteDocumentComments', 'after');
// 2007. 10. 17 모듈이 삭제될때 등록된 댓글도 모두 삭제하는 트리거 추가
if(!$oModuleModel->getTrigger('module.deleteModule', 'comment', 'controller', 'triggerDeleteModuleComments', 'after'))
$oModuleController->insertTrigger('module.deleteModule', 'comment', 'controller', 'triggerDeleteModuleComments', 'after');
// 2007. 10. 23 댓글에도 추천/ 알림 기능을 위한 컬럼 추가
if(!$oDB->isColumnExists("comments","voted_count")) {
$oDB->addColumn("comments","voted_count", "number","11");
$oDB->addIndex("comments","idx_voted_count", array("voted_count"));
}
if(!$oDB->isColumnExists("comments","notify_message")) {
$oDB->addColumn("comments","notify_message", "char","1");
}
if(!$oModuleModel->getActionForward('dispCommentAdminDeclared'))
$oModuleController->insertActionForward('comment', 'view', 'dispCommentAdminDeclared');
return new Object(0, 'success_updated');
}
/**

View file

@ -13,6 +13,59 @@
function init() {
}
/**
* @breif 댓글의 추천을 처리하는 action (Up)
**/
function procCommentVoteUp() {
$comment_srl = Context::get('target_srl');
if(!$comment_srl) return new Object(-1, 'msg_invalid_request');
$point = 1;
return $this->updateVotedCount($comment_srl, $point);
}
/**
* @breif 댓글의 추천을 처리하는 action (Down)
**/
function procCommentVoteDown() {
$comment_srl = Context::get('target_srl');
if(!$comment_srl) return new Object(-1, 'msg_invalid_request');
$point = -1;
return $this->updateVotedCount($comment_srl, $point);
}
/**
* @brief 댓글이 신고될 경우 호출되는 action
**/
function procCommentDeclare() {
$comment_srl = Context::get('target_srl');
if(!$comment_srl) return new Object(-1, 'msg_invalid_request');
return $this->declaredComment($comment_srl);
}
/**
* @brief document삭제시 해당 document의 댓글을 삭제하는 trigger
**/
function triggerDeleteDocumentComments(&$obj) {
$document_srl = $obj->document_srl;
if(!$document_srl) return new Object();
return $this->deleteComments($document_srl, true);
}
/**
* @brief module 삭제시 해당 댓글을 모두 삭제하는 trigger
**/
function triggerDeleteModuleComments(&$obj) {
$module_srl = $obj->module_srl;
if(!$module_srl) return new Object();
$oCommentController = &getAdminController('comment');
return $oCommentController->deleteModuleComments($module_srl);
}
/**
* @brief 코멘트의 권한 부여
* 세션값으로 접속상태에서만 사용 가능
@ -25,7 +78,9 @@
* @brief 댓글 입력
**/
function insertComment($obj, $manual_inserted = false) {
$obj->content = removeHackTag($obj->content);
// trigger 호출 (before)
$output = ModuleHandler::triggerCall('comment.insertComment', 'before', $obj);
if(!$output->toBool()) return $output;
// document_srl에 해당하는 글이 있는지 확인
$document_srl = $obj->document_srl;
@ -56,20 +111,20 @@
}
}
// 댓글 번호가 있으면 첨부파일 조사
if($obj->comment_srl) {
// file의 Model객체 생성
$oFileModel = &getModel('file');
// 첨부 파일의 갯수를 구함
$obj->uploaded_count = $oFileModel->getFilesCount($obj->comment_srl);
// 댓글 번호가 없다면 신규 번호 할당
} else {
$obj->comment_srl = getNextSequence();
}
if(!$obj->comment_srl) $obj->comment_srl = getNextSequence();
// 순서를 정함
$obj->list_order = $obj->comment_srl * -1;
$obj->list_order = getNextSequence() * -1;
// 내용에서 제로보드XE만의 태그를 삭제
$obj->content = preg_replace('!<\!--(Before|After)Document\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content);
// 세션에서 최고 관리자가 아니면 iframe, script 제거
if($logged_info->is_admin != 'Y') $obj->content = removeHackTag($obj->content);
if(!$obj->notify_message) $obj->notify_message = 'N';
if(!$obj->is_secret) $obj->is_secret = 'N';
// begin transaction
$oDB = &DB::getInstance();
@ -95,17 +150,35 @@
$oDocumentController = &getController('document');
// 해당글의 댓글 수를 업데이트
$output = $oDocumentController->updateCommentCount($document_srl, $comment_count, true);
$output = $oDocumentController->updateCommentCount($document_srl, $comment_count, $obj->nick_name, true);
// 댓글의 권한을 부여
$this->addGrant($obj->comment_srl);
}
// trigger 호출 (after)
if($output->toBool()) {
$trigger_output = ModuleHandler::triggerCall('comment.insertComment', 'after', $obj);
if(!$trigger_output->toBool()) {
$oDB->rollback();
return $trigger_output;
}
}
// commit
$oDB->commit();
// 원본글에 알림(notify_message)가 설정되어 있으면 메세지 보냄
if(!$manual_inserted) $oDocument->notify(Context::getLang('comment'), $obj->content);
if(!$manual_inserted) {
// 원본글에 알림(notify_message)가 설정되어 있으면 메세지 보냄
$oDocument->notify(Context::getLang('comment'), $obj->content);
// 원본 댓글이 있고 원본 댓글에 알림(notify_message)가 있으면 메세지 보냄
if($obj->parent_srl) {
$oParent = $oCommentModel->getComment($obj->parent_srl);
$oParent->notify(Context::getLang('comment'), $obj->content);
}
}
$output->add('comment_srl', $obj->comment_srl);
return $output;
@ -115,16 +188,25 @@
* @brief 댓글 수정
**/
function updateComment($obj, $is_admin = false) {
$obj->content = removeHackTag($obj->content);
// trigger 호출 (before)
$output = ModuleHandler::triggerCall('comment.updateComment', 'before', $obj);
if(!$output->toBool()) return $output;
// comment model 객체 생성
$oCommentModel = &getModel('comment');
// 원본 데이터를 가져옴
$source_obj = $oCommentModel->getComment($obj->comment_srl);
if(!$source_obj->getMemberSrl()) {
$obj->member_srl = $source_obj->get('member_srl');
$obj->user_name = $source_obj->get('user_name');
$obj->nick_name = $source_obj->get('nick_name');
$obj->email_address = $source_obj->get('email_address');
$obj->homepage = $source_obj->get('homepage');
}
// 권한이 있는지 확인
if(!$is_admin && !$source_obj->is_granted) return new Object(-1, 'msg_not_permitted');
if(!$is_admin && !$source_obj->isGranted()) return new Object(-1, 'msg_not_permitted');
if($obj->password) $obj->password = md5($obj->password);
if($obj->homepage && !eregi('^http:\/\/',$obj->homepage)) $obj->homepage = 'http://'.$obj->homepage;
@ -142,19 +224,19 @@
}
// 로그인한 유저가 작성한 글인데 nick_name이 없을 경우
if($source_obj->member_srl && !$obj->nick_name) {
$obj->member_srl = $source_obj->member_srl;
$obj->user_name = $source_obj->user_name;
$obj->nick_name = $source_obj->nick_name;
$obj->email_address = $source_obj->email_address;
$obj->homepage = $source_obj->homepage;
if($source_obj->get('member_srl')&& !$obj->nick_name) {
$obj->member_srl = $source_obj->get('member_srl');
$obj->user_name = $source_obj->get('user_name');
$obj->nick_name = $source_obj->get('nick_name');
$obj->email_address = $source_obj->get('email_address');
$obj->homepage = $source_obj->get('homepage');
}
// file의 Model객체 생성
$oFileModel = &getModel('file');
// 내용에서 제로보드XE만의 태그를 삭제
$obj->content = preg_replace('!<\!--(Before|After)Document\(([0-9]+),([0-9]+)\)-->!is', '', $obj->content);
// 첨부 파일의 갯수를 구함
$obj->uploaded_count = $oFileModel->getFilesCount($obj->document_srl);
// 세션에서 최고 관리자가 아니면 iframe, script 제거
if($logged_info->is_admin != 'Y') $obj->content = removeHackTag($obj->content);
// begin transaction
$oDB = &DB::getInstance();
@ -167,6 +249,15 @@
return $output;
}
// trigger 호출 (after)
if($output->toBool()) {
$trigger_output = ModuleHandler::triggerCall('comment.updateComment', 'after', $obj);
if(!$trigger_output->toBool()) {
$oDB->rollback();
return $trigger_output;
}
}
// commit
$oDB->commit();
@ -178,6 +269,7 @@
* @brief 댓글 삭제
**/
function deleteComment($comment_srl, $is_admin = false) {
// comment model 객체 생성
$oCommentModel = &getModel('comment');
@ -186,12 +278,16 @@
if($comment->comment_srl != $comment_srl) return new Object(-1, 'msg_invalid_request');
$document_srl = $comment->document_srl;
// trigger 호출 (before)
$output = ModuleHandler::triggerCall('comment.deleteComment', 'before', $comment);
if(!$output->toBool()) return $output;
// 해당 댓글에 child가 있는지 확인
$child_count = $oCommentModel->getChildCommentCount($comment_srl);
if($child_count>0) return new Object(-1, 'fail_to_delete_have_children');
// 권한이 있는지 확인
if(!$is_admin && !$comment->is_granted) return new Object(-1, 'msg_not_permitted');
if(!$is_admin && !$comment->isGranted()) return new Object(-1, 'msg_not_permitted');
// begin transaction
$oDB = &DB::getInstance();
@ -205,12 +301,6 @@
return $output;
}
// 첨부 파일 삭제
if($comment->uploaded_count) {
$oFileController = &getController('file');
$oFileController->deleteFiles($comment->module_srl, $comment_srl);
}
// 댓글 수를 구해서 업데이트
$comment_count = $oCommentModel->getCommentCount($document_srl);
@ -218,12 +308,21 @@
$oDocumentController = &getController('document');
// 해당글의 댓글 수를 업데이트
$output = $oDocumentController->updateCommentCount($document_srl, $comment_count);
$output = $oDocumentController->updateCommentCount($document_srl, $comment_count, null, false);
if(!$output->toBool()) {
$oDB->rollback();
return $output;
}
// trigger 호출 (after)
if($output->toBool()) {
$trigger_output = ModuleHandler::triggerCall('comment.deleteComment', 'after', $comment);
if(!$trigger_output->toBool()) {
$oDB->rollback();
return $trigger_output;
}
}
// commit
$oDB->commit();
@ -247,5 +346,128 @@
return $output;
}
/**
* @brief 해당 comment의 추천수 증가
**/
function updateVotedCount($comment_srl, $point = 1) {
// 세션 정보에 추천 정보가 있으면 중단
if($_SESSION['voted_comment'][$comment_srl]) return new Object(-1, 'failed_voted');
// 문서 원본을 가져옴
$oCommentModel = &getModel('comment');
$oComment = $oCommentModel->getComment($comment_srl, false, false);
// 글의 작성 ip와 현재 접속자의 ip가 동일하면 패스
if($oComment->get('ipaddress') == $_SERVER['REMOTE_ADDR']) {
$_SESSION['voted_comment'][$comment_srl] = true;
return new Object(-1, 'failed_voted');
}
// comment의 작성자가 회원일때 조사
if($oComment->get('member_srl')) {
// member model 객체 생성
$oMemberModel = &getModel('member');
$member_srl = $oMemberModel->getLoggedMemberSrl();
// 글쓴이와 현재 로그인 사용자의 정보가 일치하면 읽었다고 생각하고 세션 등록후 패스
if($member_srl && $member_srl == $oComment->get('member_srl')) {
$_SESSION['voted_comment'][$comment_srl] = true;
return new Object(-1, 'failed_voted');
}
}
// 로그인 사용자이면 member_srl, 비회원이면 ipaddress로 판단
if($member_srl) {
$args->member_srl = $member_srl;
} else {
$args->ipaddress = $_SERVER['REMOTE_ADDR'];
}
$args->comment_srl = $comment_srl;
$output = executeQuery('comment.getCommentVotedLogInfo', $args);
// 로그 정보에 추천 로그가 있으면 세션 등록후 패스
if($output->data->count) {
$_SESSION['voted_comment'][$comment_srl] = true;
return new Object(-1, 'failed_voted');
}
// 추천수 업데이트
$args->voted_count = $oComment->get('voted_count') + $point;
$output = executeQuery('comment.updateVotedCount', $args);
// 로그 남기기
$output = executeQuery('comment.insertCommentVotedLog', $args);
// 세션 정보에 남김
$_SESSION['voted_comment'][$comment_srl] = true;
// 결과 리턴
return new Object(0, 'success_voted');
}
/**
* @brief 댓글 신고
**/
function declaredComment($comment_srl) {
// 세션 정보에 신고 정보가 있으면 중단
if($_SESSION['declared_comment'][$comment_srl]) return new Object(-1, 'failed_declared');
// 이미 신고되었는지 검사
$args->comment_srl = $comment_srl;
$output = executeQuery('comment.getDeclaredComment', $args);
if(!$output->toBool()) return $output;
// 문서 원본을 가져옴
$oCommentModel = &getModel('comment');
$oComment = $oCommentModel->getComment($comment_srl, false, false);
// 글의 작성 ip와 현재 접속자의 ip가 동일하면 패스
if($oComment->get('ipaddress') == $_SERVER['REMOTE_ADDR']) {
$_SESSION['declared_comment'][$comment_srl] = true;
return new Object(-1, 'failed_declared');
}
// comment의 작성자가 회원일때 조사
if($oComment->get('member_srl')) {
// member model 객체 생성
$oMemberModel = &getModel('member');
$member_srl = $oMemberModel->getLoggedMemberSrl();
// 글쓴이와 현재 로그인 사용자의 정보가 일치하면 읽었다고 생각하고 세션 등록후 패스
if($member_srl && $member_srl == $oComment->get('member_srl')) {
$_SESSION['declared_comment'][$comment_srl] = true;
return new Object(-1, 'failed_declared');
}
}
// 로그인 사용자이면 member_srl, 비회원이면 ipaddress로 판단
if($member_srl) {
$args->member_srl = $member_srl;
} else {
$args->ipaddress = $_SERVER['REMOTE_ADDR'];
}
$args->comment_srl = $comment_srl;
$output = executeQuery('comment.getCommentDeclaredLogInfo', $args);
// 로그 정보에 신고 로그가 있으면 세션 등록후 패스
if($output->data->count) {
$_SESSION['declared_comment'][$comment_srl] = true;
return new Object(-1, 'failed_declared');
}
// 신고글 추가
if($output->data->declared_count > 0) $output = executeQuery('comment.updateDeclaredComment', $args);
else $output = executeQuery('comment.insertDeclaredComment', $args);
if(!$output->toBool()) return $output;
// 로그 남기기
$output = executeQuery('comment.insertCommentDeclaredLog', $args);
// 세션 정보에 남김
$_SESSION['declared_comment'][$comment_srl] = true;
$this->setMessage('success_declared');
}
}
?>

View file

@ -0,0 +1,237 @@
<?php
/**
* @class commentItem
* @author zero (zero@nzeo.com)
* @brief comment 객체
**/
class commentItem extends Object {
var $comment_srl = 0;
function commentItem($comment_srl = 0) {
$this->comment_srl = $comment_srl;
$this->_loadFromDB();
}
function setComment($comment_srl) {
$this->comment_srl = $comment_srl;
$this->_loadFromDB();
}
function _loadFromDB() {
if(!$this->comment_srl) return;
$args->comment_srl = $this->comment_srl;
$output = executeQuery('comment.getComment', $args);
$this->setAttribute($output->data);
}
function setAttribute($attribute) {
if(!$attribute->comment_srl) {
$this->comment_srl = null;
return;
}
$this->comment_srl = $attribute->comment_srl;
$this->adds($attribute);
// 기존 스킨의 호환을 위해 변수를 객체 자신에 재선언
if(count($attribute)) foreach($attribute as $key => $val) $this->{$key} = $val;
}
function isExists() {
return $this->comment_srl ? true : false;
}
function isGranted() {
if($_SESSION['own_comment'][$this->comment_srl]) return true;
if(!Context::get('is_logged')) return false;
$logged_info = Context::get('logged_info');
if($logged_info->is_admin == 'Y') return true;
if($this->get('member_srl') && $this->get('member_srl') == $logged_info->member_srl) return true;
return false;
}
function setGrant() {
$_SESSION['own_comment'][$this->comment_srl] = true;
$this->is_granted = true;
}
function isEditable() {
if($this->isGranted() || !$this->get('member_srl')) return true;
return false;
}
function isSecret() {
return $this->get('is_secret') == 'Y' ? true : false;
}
function isAccessible() {
if($this->isGranted()) return true;
if(!$this->isSecret()) return true;
$oDocumentModel = &getModel('document');
$oDocument = $oDocumentModel->getDocument($this->get('document_srl'));
if($oDocument->isGranted()) return true;
return false;
}
function useNotify() {
return $this->get('notify_message')=='Y' ? true : false;
}
function notify($type, $content) {
// useNotify가 아니면 return
if(!$this->useNotify()) return;
// 글쓴이가 로그인 유저가 아니면 패스~
if(!$this->get('member_srl')) return;
// 현재 로그인한 사용자와 글을 쓴 사용자를 비교하여 동일하면 return
$logged_info = Context::get('logged_info');
if($logged_info->member_srl == $this->get('member_srl')) return;
// 원본글의 주소를 구함
$oDocumentModel = &getModel('document');
$oDocument = $oDocumentModel->getDocument($this->get('document_srl'));
// 변수 정리
if($type) $title = "[".$type."] ";
$title .= cut_str(strip_tags($content), 10, '...');
$content = sprintf('%s<br /><br />from : <a href="%s#comment_%s" onclick="window.open(this.href);return false;">%s</a>',$content, $oDocument->getPermanentUrl(), $this->get('comment_srl'), $oDocument->getPermanentUrl());
$receiver_srl = $this->get('member_srl');
$sender_member_srl = $logged_info->member_srl;
// 쪽지 발송
$oMemberController = &getController('member');
$oMemberController->sendMessage($sender_member_srl, $receiver_srl, $title, $content, false);
}
function isExistsHomepage() {
if(trim($this->get('homepage'))) return true;
return false;
}
function getHomepageUrl() {
$url = trim($this->get('homepage'));
if(!$url) return;
if(!eregi("^http:\/\/",$url)) $url = "http://".$url;
return $url;
}
function getMemberSrl() {
return $this->get('member_srl');
}
function getUserID() {
return htmlspecialchars($this->get('user_id'));
}
function getUserName() {
return htmlspecialchars($this->get('user_name'));
}
function getNickName() {
return htmlspecialchars($this->get('nick_name'));
}
function getContentText($strlen = 0) {
if($this->isSecret() && !$this->isAccessible()) return Context::getLang('msg_is_secret');
$content = $this->get('content');
if($strlen) return cut_str(strip_tags($content),$strlen,'...');
return htmlspecialchars($content);
}
function getContent($add_comment_info = true) {
if($this->isSecret() && !$this->isAccessible()) return Context::getLang('msg_is_secret');
$content = $this->get('content');
// OL/LI 태그를 위한 치환 처리
$content = preg_replace('!<(ol|ul|blockquote)>!is','<\\1 style="margin-left:40px;">',$content);
// url에 대해서 정규표현식으로 치환
$content = preg_replace('!([^>^"^\'^=])(http|https|ftp|mms):\/\/([^ ^<^"^\']*)!is','$1<a href="$2://$3" onclick="window.open(this.href);return false;">$2://$3</a>',' '.$content);
if(!$add_comment_info) return $content;
$content = sprintf(
'<!--BeforeComment(%d,%d)--><div class="comment_%d_%d">%s</div><div class="comment_popup_menu"><span class="comment_popup_menu comment_%d">%s</span></div><!--AfterComment(%d,%d)-->',
$this->comment_srl, $this->get('member_srl'),
$this->comment_srl, $this->get('member_srl'),
$content,
$this->comment_srl, Context::getLang('cmd_comment_do'),
$this->comment_srl, $this->get('member_srl'),
$this->comment_srl, $this->get('member_srl')
);
return $content;
}
function getSummary($str_size = 50) {
$content = htmlspecialchars(strip_tags(str_replace("&nbsp;"," ",$this->getContent(false))));
return cut_str($content, $str_size, '...');
}
function getRegdate($format = 'Y.m.d H:i:s') {
return zdate($this->get('regdate'), $format);
}
function getRegdateTime() {
$regdate = $this->get('regdate');
$year = substr($regdate,0,4);
$month = substr($regdate,4,2);
$day = substr($regdate,6,2);
$hour = substr($regdate,8,2);
$min = substr($regdate,10,2);
$sec = substr($regdate,12,2);
return mktime($hour,$min,$sec,$month,$day,$year);
}
function getRegdateGM() {
return $this->getRegdate('D, d M Y H:i:s').' '.$GLOBALS['_time_zone'];
}
function getUpdate($format = 'Y.m.d H:i:s') {
return zdate($this->get('last_update'), $format);
}
function getUpdateTime() {
$year = substr($this->get('last_update'),0,4);
$month = substr($this->get('last_update'),4,2);
$day = substr($this->get('last_update'),6,2);
$hour = substr($this->get('last_update'),8,2);
$min = substr($this->get('last_update'),10,2);
$sec = substr($this->get('last_update'),12,2);
return mktime($hour,$min,$sec,$month,$day,$year);
}
function getUpdateGM() {
return gmdate("D, d M Y H:i:s", $this->getUpdateTime());
}
function hasUploadedFiles() {
if($this->isSecret() && !$this->isGranted()) return false;
return $this->get('uploaded_count')? true : false;
}
function getUploadedFiles() {
if($this->isSecret() && !$this->isGranted()) return;
if(!$this->get('uploaded_count')) return;
$oFileModel = &getModel('file');
$file_list = $oFileModel->getFiles($this->comment_srl, $is_admin);
return $file_list;
}
}
?>

View file

@ -13,6 +13,48 @@
function init() {
}
/**
* @brief 선택된 게시물의 팝업메뉴 표시
*
* 인쇄, 스크랩, 추천, 비추천, 신고 기능 추가
**/
function getCommentMenu() {
// 요청된 게시물 번호와 현재 로그인 정보 구함
$comment_srl = Context::get('target_srl');
$mid = Context::get('cur_mid');
$logged_info = Context::get('logged_info');
$act = Context::get('cur_act');
// menu_list 에 "표시할글,target,url" 을 배열로 넣는다
$menu_list = array();
// trigger 호출
ModuleHandler::triggerCall('comment.getCommentMenu', 'before', $menu_list);
// 추천 버튼 추가
$menu_str = Context::getLang('cmd_vote');
$menu_link = sprintf("doCallModuleAction('comment','procCommentVoteUp','%s')", $comment_srl);
$menu_list[] = sprintf("\n%s,%s,%s", '', $menu_str, $menu_link);
// 비추천 버튼 추가
$menu_str = Context::getLang('cmd_vote_down');
$menu_link = sprintf("doCallModuleAction('comment','procCommentVoteDown','%s')", $comment_srl);
$menu_list[] = sprintf("\n%s,%s,%s", '', $menu_str, $menu_link);
// 신고 기능 추가
$menu_str = Context::getLang('cmd_declare');
$menu_link = sprintf("doCallModuleAction('comment','procCommentDeclare','%s')", $comment_srl);
$menu_list[] = sprintf("\n%s,%s,%s", '', $menu_str, $menu_link);
// trigger 호출 (after)
ModuleHandler::triggerCall('comment.getCommentMenu', 'after', $menu_list);
// 정보를 저장
$this->add("menu_list", implode("\n",$menu_list));
}
/**
* @brief comment_srl에 권한이 있는지 체크
*
@ -34,24 +76,11 @@
/**
* @brief 댓글 가져오기
**/
function getComment($comment_srl, $is_admin = false) {
if(!$comment_srl) return;
$args->comment_srl = $comment_srl;
$output = executeQuery('comment.getComment', $args);
$comment = $output->data;
function getComment($comment_srl=0, $is_admin = false) {
$oComment = new commentItem($comment_srl);
if($is_admin) $oComment->setGrant();
// 첨부파일 가져오기
if($comment->uploaded_count) {
$oFileModel = &getModel('file');
$file_list = $oFileModel->getFiles($comment_srl, $is_admin);
$comment->uploaded_list = $file_list;
}
// 로그인 사용자의 경우 로그인 정보를 일단 구해 놓음
$logged_info = Context::get('logged_info');
if($is_admin || $this->isGranted($comment_srl) || $comment->member_srl == $logged_info->member_srl) $comment->is_granted = true;
return $comment;
return $oComment;
}
/**
@ -60,9 +89,25 @@
function getComments($comment_srl_list) {
if(is_array($comment_srl_list)) $comment_srls = implode(',',$comment_srl_list);
// DB에서 가져옴
$args->comment_srls = $comment_srls;
$output = executeQuery('comment.getComments', $args);
return $output->data;
if(!$output->toBool()) return;
$comment_list = $output->data;
if(!$comment_list) return;
if(!is_array($comment_list)) $comment_list = array($comment_list);
$comment_count = count($comment_list);
foreach($comment_list as $key => $attribute) {
if(!$attribute->comment_srl) continue;
$oComment = null;
$oComment = new commentItem();
$oComment->setAttribute($attribute);
if($is_admin) $oComment->setGrant();
$result[$attribute->comment_srl] = $oComment;
}
return $result;
}
/**
@ -93,7 +138,22 @@
$output = executeQuery('comment.getNewestCommentList', $args);
if(!$output->toBool()) return $output;
return $output;
$comment_list = $output->data;
if($comment_list) {
if(!is_array($comment_list)) $comment_list = array($comment_list);
$comment_count = count($comment_list);
foreach($comment_list as $key => $attribute) {
if(!$attribute->comment_srl) continue;
$oComment = null;
$oComment = new commentItem();
$oComment->setAttribute($attribute);
$oComment->setGrant();
$result[$key] = $oComment;
}
$output->data = $result;
}
return $result;
}
/**
@ -117,9 +177,6 @@
// 로그인 사용자의 경우 로그인 정보를 일단 구해 놓음
$logged_info = Context::get('logged_info');
// 첨부파일이 있을 경우를 대비한 File 모듈의 model객체 미리 생성
$oFileModel = &getModel('file');
// loop를 돌면서 코멘트의 계층 구조 만듬
for($i=$comment_count-1;$i>=0;$i--) {
$comment_srl = $source_list[$i]->comment_srl;
@ -136,12 +193,6 @@
if($is_admin || $this->isGranted($comment_srl) || $member_srl == $logged_info->member_srl) $source_list[$i]->is_granted = true;
// 첨부파일 가져오기
if($source_list[$i]->uploaded_count) {
$file_list = $oFileModel->getFiles($comment_srl, $is_admin);
$source_list[$i]->uploaded_list = $file_list;
}
// 목록을 만듬
$list[$comment_srl] = $source_list[$i];
@ -161,14 +212,20 @@
function _arrangeComment(&$comment_list, $list, $depth) {
if(!count($list)) return;
foreach($list as $key => $val) {
$oCommentItem = new commentItem();
if($val->child) {
$tmp = $val;
$tmp->depth = $depth;
$comment_list[$tmp->comment_srl] = $tmp;
$oCommentItem->setAttribute($tmp);
$comment_list[$tmp->comment_srl] = $oCommentItem;
$this->_arrangeComment($comment_list,$val->child,$depth+1);
} else {
$val->depth = $depth;
$comment_list[$val->comment_srl] = $val;
$oCommentItem->setAttribute($val);
$comment_list[$val->comment_srl] = $oCommentItem;
}
}
}

View file

@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<module version="0.1">
<module version="0.1" category="utility">
<title xml:lang="ko">댓글</title>
<title xml:lang="jp">コメント</title>
<title xml:lang="zh-CN">评论</title>

View file

@ -2,7 +2,13 @@
<module>
<grants />
<actions>
<action name="getCommentMenu" type="model" standalone="true"/>
<action name="dispCommentAdminList" type="view" admin_index="true" standalone="true" />
<action name="dispCommentAdminDeclared" type="view" standalone="true" />
<action name="procCommentVoteUp" type="controller" standalone="true" />
<action name="procCommentVoteDown" type="controller" standalone="true" />
<action name="procCommentDeclare" type="controller" standalone="true" />
<action name="procCommentAdminDeleteChecked" type="controller" standalone="true" />
<action name="procCommentAdminDeleteChecked" type="controller" standalone="true" />
</actions>
</module>

View file

@ -4,10 +4,14 @@
* @author zero <zero@nzeo.com>
* @brief comment module's basic language pack
**/
$lang->cmd_comment_do = '이 댓글을..';
$lang->comment_list = '댓글 목록';
$lang->cmd_delete_checked_comment = 'Delete selected item';
$lang->msg_cart_is_null = 'Please select an article to delete';
$lang->msg_checked_comment_is_deleted = '%d comments were deleted successfully';
$lang->msg_checked_comment_is_deleted = '%d comment(s) is(are) successfully deleted.';
$lang->search_target_list = array(
'content' => 'Content',

View file

@ -4,6 +4,10 @@
* @auhor zero <zero@nzeo.com>
* @sumario Paquete del idioma español para el módulo de comentarios.
**/
$lang->cmd_comment_do = '이 댓글을..';
$lang->comment_list = '댓글 목록';
$lang->cmd_delete_checked_comment = 'Eliminar lo seleccionado' ;
$lang->msg_cart_is_null = 'Selecciona el commentario que desea eliminar';

View file

@ -4,6 +4,10 @@
* @author zero <zero@nzeo.com> 翻訳RisaPapa
* @brief コメント(comment) モジュールの基本言語パッケージ
**/
$lang->cmd_comment_do = '이 댓글을..';
$lang->comment_list = '댓글 목록';
$lang->cmd_delete_checked_comment = '選択項目削除';
$lang->msg_cart_is_null = '削除するコメントを選択してください';

View file

@ -5,6 +5,9 @@
* @brief 댓글(comment) 모듈의 기본 언어팩
**/
$lang->cmd_comment_do = '이 댓글을..';
$lang->comment_list = '댓글 목록';
$lang->cmd_toggle_checked_comment = '선택항목 반전';
$lang->cmd_delete_checked_comment = '선택항목 삭제';

View file

@ -4,6 +4,10 @@
* @author zero <zero@nzeo.com>
* @brief 评论(comment)模块语言包
**/
$lang->cmd_comment_do = '이 댓글을..';
$lang->comment_list = '댓글 목록';
$lang->cmd_toggle_checked_comment = '反选';
$lang->cmd_delete_checked_comment = '删除所选';

View file

@ -0,0 +1,15 @@
<query id="getCommentDeclaredLogInfo" action="select">
<tables>
<table name="comment_declared_log" />
</tables>
<columns>
<column name="count(*)" alias="count" />
</columns>
<conditions>
<condition operation="equal" column="comment_srl" var="comment_srl" filter="number" notnull="notnull" />
<group pipe="and">
<condition operation="equal" column="member_srl" var="member_srl" filter="number" pipe="and" />
<condition operation="equal" column="ipaddress" var="ipaddress" pipe="and" />
</group>
</conditions>
</query>

View file

@ -0,0 +1,15 @@
<query id="getCommentVotedLogInfo" action="select">
<tables>
<table name="comment_voted_log" />
</tables>
<columns>
<column name="count(*)" alias="count" />
</columns>
<conditions>
<condition operation="equal" column="comment_srl" var="comment_srl" filter="number" notnull="notnull" />
<group pipe="and">
<condition operation="equal" column="member_srl" var="member_srl" filter="number" pipe="and" />
<condition operation="equal" column="ipaddress" var="ipaddress" pipe="and" />
</group>
</conditions>
</query>

View file

@ -0,0 +1,8 @@
<query id="getDeclaredComment" action="select">
<tables>
<table name="comment_declared" />
</tables>
<conditions>
<condition operation="equal" column="comment_srl" var="comment_srl" filter="number" notnull="notnull" />
</conditions>
</query>

View file

@ -0,0 +1,18 @@
<query id="getDeclaredList" action="select">
<tables>
<table name="comments" alias="comments"/>
<table name="comment_declared" alias="comment_declared"/>
</tables>
<columns>
<column name="*" />
</columns>
<conditions>
<condition operation="in" column="comments.comment_srl" default="comment_declared.comment_srl" />
</conditions>
<navigation>
<index var="sort_index" default="comment_declared.declared_count" order="order_type" />
<list_count var="list_count" default="20" />
<page_count var="page_count" default="10" />
<page var="page" default="1" />
</navigation>
</query>

View file

@ -8,6 +8,7 @@
<column name="parent_srl" var="parent_srl" filter="number" default="0" />
<column name="document_srl" var="document_srl" filter="number" notnull="notnull" />
<column name="is_secret" var="is_secret" default="N" />
<column name="notify_message" var="notify_message" default="N" />
<column name="content" var="content" notnull="notnull" />
<column name="password" var="password" minlength="2" maxlength="60" />
<column name="nick_name" var="nick_name" notnull="notnull" minlength="1" maxlength="40" />

View file

@ -0,0 +1,11 @@
<query id="insertCommentDeclaredLog" action="insert">
<tables>
<table name="comment_declared_log" />
</tables>
<columns>
<column name="comment_srl" var="comment_srl" filter="number" default="0" notnull="notnull" />
<column name="member_srl" var="member_srl" filter="number" default="0" />
<column name="ipaddress" var="ipaddress" default="ipaddress()" />
<column name="regdate" var="regdate" default="curdate()" />
</columns>
</query>

View file

@ -0,0 +1,11 @@
<query id="insertCommentVotedLog" action="insert">
<tables>
<table name="comment_voted_log" />
</tables>
<columns>
<column name="comment_srl" var="comment_srl" filter="number" default="0" notnull="notnull" />
<column name="member_srl" var="member_srl" filter="number" default="0" />
<column name="ipaddress" var="ipaddress" default="ipaddress()" />
<column name="regdate" var="regdate" default="curdate()" />
</columns>
</query>

View file

@ -0,0 +1,9 @@
<query id="insertDeclaredComment" action="insert">
<tables>
<table name="comment_declared" />
</tables>
<columns>
<column name="comment_srl" var="comment_srl" filter="number" notnull="notnull" />
<column name="declared_count" default="1" />
</columns>
</query>

View file

@ -6,6 +6,7 @@
<column name="module_srl" var="module_srl" filter="number" default="0" />
<column name="parent_srl" var="parent_srl" filter="number" default="0" />
<column name="is_secret" var="is_secret" default="N" />
<column name="notify_message" var="notify_message" default="N" />
<column name="content" var="content" notnull="notnull" />
<column name="password" var="password" minlength="2" maxlength="60" />
<column name="user_name" var="user_name" default="" />

View file

@ -0,0 +1,11 @@
<query id="updateDeclaredComment" action="update">
<tables>
<table name="comment_declared" />
</tables>
<columns>
<column name="declared_count" default="plus(1)" />
</columns>
<conditions>
<condition operation="equal" column="comment_srl" var="comment_srl" filter="number" notnull="notnull" />
</conditions>
</query>

View file

@ -0,0 +1,11 @@
<query id="updateVotedCount" action="update">
<tables>
<table name="comments" />
</tables>
<columns>
<column name="voted_count" var="voted_count" notnull="notnull" />
</columns>
<conditions>
<condition operation="equal" column="comment_srl" var="comment_srl" filter="number" notnull="notnull" />
</conditions>
</query>

View file

@ -0,0 +1,4 @@
<table name="comment_declared">
<column name="comment_srl" type="number" size="11" notnull="notnull" primary_key="primary_key" />
<column name="declared_count" type="number" size="11" default="0" notnull="notnull" index="idx_declared_count" />
</table>

View file

@ -0,0 +1,6 @@
<table name="comment_declared_log">
<column name="comment_srl" type="number" size="11" notnull="notnull" index="idx_comment_srl" />
<column name="member_srl" type="number" size="11" notnull="notnull" index="idx_member_srl" />
<column name="ipaddress" type="varchar" size="128" notnull="notnull" index="idx_ipaddress"/>
<column name="regdate" type="date" index="idx_regdate" />
</table>

View file

@ -0,0 +1,6 @@
<table name="comment_voted_log">
<column name="comment_srl" type="number" size="11" notnull="notnull" index="idx_comment_srl" />
<column name="member_srl" type="number" size="11" notnull="notnull" index="idx_member_srl" />
<column name="ipaddress" type="varchar" size="128" notnull="notnull" index="idx_ipaddress"/>
<column name="regdate" type="date" index="idx_regdate" />
</table>

View file

@ -5,6 +5,8 @@
<column name="parent_srl" type="number" size="11" default="0" notnull="notnull" />
<column name="is_secret" type="char" size="1" default="N" notnull="notnull" />
<column name="content" type="bigtext" notnull="notnull" />
<column name="voted_count" type="number" size="11" default="0" notnull="notnull" index="idx_voted_count" />
<column name="notify_message" type="char" size="1" default="N" notnull="notnull" />
<column name="password" type="varchar" size="60" />
<column name="user_id" type="varchar" size="80" />
<column name="user_name" type="varchar" size="80" notnull="notnull" />

View file

@ -1,7 +1,5 @@
<!--%import("filter/delete_checked.xml")-->
<!--%import("js/comment_admin.js")-->
<h3>{$lang->comment} <span class="gray">{$lang->cmd_management}</span></h3>
<!--#include("./header.html")-->
<!-- 정보 -->
<div class="tableSummaryType1">
@ -12,18 +10,26 @@
<input type="hidden" name="page" value="{$page}" />
<!-- 목록 -->
<table cellspacing="0" class="tableType4">
<table cellspacing="0" class="adminTable">
<col width="50" />
<col />
<col width="120" />
<col width="80" />
<col width="100" />
<col width="70" />
<col width="50" />
<thead>
<tr>
<th scope="col"><input type="checkbox" onclick="checkboxSelectAll(this.form, 'cart'); return false;" /></th>
<th scope="col">
<div class="nowrap">
<select name="module_srl" class="mid_list" id="module_srl">
<select name="module_srl" id="module_srl">
<option value="">{$lang->module}</option>
<!--@foreach($mid_list as $key => $val)-->
<option value="{$val->module_srl}" <!--@if($module_srl == $val->module_srl)-->selected="selected"<!--@end-->>{$val->browser_title}</option>
<!--@end-->
</select><a href="#" onclick="location.href=current_url.setQuery('module_srl',xGetElementById('module_srl').options[xGetElementById('module_srl').selectedIndex].value);return false;" class="button"><span>GO</span></a>
</select>
<input type="button" name="go_button" id="go_button" value="GO" class="buttonTypeGo" onclick="location.href=current_url.setQuery('module_srl',xGetElementById('module_srl').options[xGetElementById('module_srl').selectedIndex].value);return false;"/>
</div>
</th>
<th scope="col">{$lang->user_name}</th>
@ -36,9 +42,7 @@
<tbody>
<!--@foreach($comment_list as $no => $val)-->
<tr>
<td rowspan="2" class="tahoma">
{$no}
</td>
<td rowspan="2" class="tahoma">{$no}</td>
<td class="blue"><a href="./?mid={$module_list[$val->module_srl]->mid}" onclick="window.open(this.href);return false">{htmlspecialchars($module_list[$val->module_srl]->browser_title)}</a></td>
<td><div class="member_{$val->member_srl}">{htmlspecialchars($val->nick_name)}</div></td>
<td class="tahoma">{zdate($val->regdate,"Y-m-d")}</td>
@ -47,7 +51,7 @@
<td class="blue"><a href="{getUrl('','document_srl',$val->document_srl)}#comment_{$val->comment_srl}" onclick="window.open(this.href);return false;">{$lang->cmd_move}</a></td>
</tr>
<tr>
<td colspan="7" class="left">
<td colspan="6" class="left">
<input type="checkbox" name="cart" value="{$val->comment_srl}" />
{cut_str(htmlspecialchars(strip_tags($val->content)),100,'...')}
</td>

View file

@ -0,0 +1,66 @@
<!--%import("filter/delete_checked.xml")-->
<!--#include("header.html")-->
<!-- 정보 -->
<div class="tableSummaryType1">
Total <strong>{number_format($total_count)}</strong>, Page <strong>{number_format($page)}</strong>/{number_format($total_page)}
</div>
<form id="fo_list" action="./" method="get" onsubmit="return procFilter(this, delete_checked)">
<input type="hidden" name="page" value="{$page}" />
<!-- 목록 -->
<table cellspacing="0" class="adminTable">
<col width="60" />
<col />
<col width="120" />
<col width="80" />
<col width="80" />
<col width="70" />
<col width="50" />
<thead>
<tr>
<th scope="col"><input type="checkbox" onclick="checkboxSelectAll(this.form, 'cart'); return false;" /></th>
<th scope="col">{$lang->comment}</th>
<th scope="col">{$lang->user_name}</th>
<th scope="col">{$lang->date}</th>
<th scope="col">{$lang->cmd_declare}</th>
<th scope="col">{$lang->ipaddress}</th>
<th scope="col">{$lang->cmd_move}</th>
</tr>
</thead>
<tbody>
<!--@foreach($comment_list as $no => $oComment)-->
<tr>
<td class="tahoma">{$no}</td>
<td class="left"><input type="checkbox" name="cart" value="{$oComment->get('comment_srl')}" /> {$oComment->getSummary(100)}</td>
<td><div class="member_{$oComment->getMemberSrl()}">{$oComment->getNickName()}</div></td>
<td class="tahoma">{$oComment->getRegdate("Y-m-d")}</td>
<td class="tahoma red"><strong>{$oComment->get('declared_count')}</strong></td>
<td class="tahoma">{$oComment->get('ipaddress')}</td>
<td class="blue"><a href="{getUrl('','document_srl',$oComment->get('document_srl'))}#comment_{$oComment->get('comment_srl')}" onclick="window.open(this.href);return false;">{$lang->cmd_move}</a></td>
</tr>
<!--@end-->
</tbody>
</table>
<!-- 버튼 -->
<div class="fr gap1">
<a href="javascript:checkboxSelectAll('fo_list', 'cart', true)" class="button"><span>{$lang->cmd_select_all}</span></a>
<a href="javascript:checkboxSelectAll('fo_list', 'cart')" class="button"><span>{$lang->cmd_reverse_all}</span></a>
<span class="button"><input type="submit" value="{$lang->cmd_delete_checked_comment}" /></span>
</div>
</form>
<!-- 페이지 네비게이션 -->
<div class="pageNavigation">
<a href="{getUrl('page','','module_srl','')}" class="goToFirst"><img src="../../admin/tpl/images/bottomGotoFirst.gif" alt="{$lang->first_page}" width="7" height="5" /></a>
<!--@while($page_no = $page_navigation->getNextPage())-->
<!--@if($page == $page_no)-->
<span class="current">{$page_no}</span>
<!--@else-->
<a href="{getUrl('page',$page_no,'module_srl','')}">{$page_no}</a>
<!--@end-->
<!--@end-->
<a href="{getUrl('page',$page_navigation->last_page,'module_srl','')}" class="goToLast"><img src="../../admin/tpl/images/bottomGotoLast.gif" alt="{$lang->last_page}" width="7" height="5" /></a>
</div>

View file

@ -0,0 +1,10 @@
<!--%import("js/comment_admin.js")-->
<h3>{$lang->comment} <span class="gray">{$lang->cmd_management}</span></h3>
<div class="header4 gap1">
<ul class="localNavigation">
<li <!--@if($act=='dispCommentAdminList')-->class="on"<!--@end-->><a href="{getUrl('act','dispCommentAdminList')}">{$lang->comment_list}</a></li>
<li <!--@if($act=='dispCommentAdminDeclared')-->class="on"<!--@end-->><a href="{getUrl('act','dispCommentAdminDeclared')}">{$lang->cmd_declared_list}</a></li>
</ul>
</div>