Sejin7940 
(http://sejin7940.co.kr)
 I. XE 내장함수 사용방법 
 II. 모듈간의 연결 – Trigger 
 III. 실시간반응 – exec_xml/json 
 IV. 쿼리사용 - $oDB = &DB::getInstance();
 질문) 게시글에 글쓴이 회원정보들이 나타나게 하 
고 싶은데 어떻게 하나요? 
 질문) 글을 추천한 추천인 목록을 스킨에 출력하려 
면 어떻게 해야하나요? 
 질문) 어떤 기능을 구현하려면 어딜 어떻게 고쳐야 
하나요? 해당 페이지 파일은 어디에?
 1. 함수 이름 규칙 
 
1) Type + 모듈이름 + (Admin) + 고유이름 
 ( disp 는 view , proc 는 controller, get 은 model 파일에 
있음.) 
 
2) view 파일들은 해당 함수에 
setTemplateFile(‘파일명’) 에 정의됨 
( 스킨 또는 tpl 내에 파일명.html 형태) 
 (getModel 등은 config/func.inc.php 에 정의되어있기에 XE 어디서나 사용가능)
 2. action 미리 선언 - module.xml 미리 정의 
 1) Url로 Act 변수를 직접 사용 – 주로 view 관련 disp action 
( 회원가입-dispMemberSignUpForm) 
 2) exec_xml 나 exec_json 등에서 사용하려는 경우 
 - 행위 반응 proc action ( procDocumentVoteUp ) 
 - 목록 추출 disp action ( dispBoardContentList ) 
 3) 각 모듈의 module.xml 에 정의를 해줘야 인식됨 
 <action name="dispMemberInfo" type="view“> 
(참고) index="true“ 는 해당 모듈에서 별도의 act 없을때 기본 실행함수 
 admin_index=“true” 는 관리자화면에서 기본act
 3. 필요한 함수를 바로 선언해서 사용 
 1) getModel(‘모듈’)->함수, getController(‘모듈’)–>함수 
 getView(‘모듈’)->함수 형태로 사용 
 2) 함수별로 전달해야하는 변수값을 확인하고 받는 리턴값을 
확인해서 사용 
 3) 함수들은 모듈, 애드온, 위젯뿐만 아니라, 
 레이아웃이나 스킨 등에서도 자유롭게 사용이 가능. 
 (스킨소스를 최대한 간편하게 하기 위해 모듈 내부에서 미리 선언해 변수 
화한것 뿐)
 4. 예) 게시판 스킨 view 에서, 작성자 정보 출력 
 {@ 
 $oMemberModel = getModel('member'); 
 $writer_info = $oMemberModel- 
>getMemberInfoByMemeberSrl($oDocument- 
>getMemberSrl()); 
 } 
 닉네임 : {$oDocument->getNickName()} <br/> 
 이름 : {$oDocument->getUserName()} <br/> 
 연락처 : {str_replace('|@|','-',$writer_info->tel)} <br/> 
 주소 : {str_replace('|@|',' ',$writer_info->address)}
 5. 참고) $oDocument, $oComment 
 
$oDocument 는 document_srl 값을 기준으로 글정보를 함 
수화한 변수 
 $oDocument = $oDocumentModel- 
>getDocument($document_srl); 로 구해진 거고 
 이를 통해 사용가능한 함수들은 document.item.php 파일에 
정의되어있다. 
 댓글도 마찬가지로 
 $oComment = $oCommentModel- 
>getComment($comment_srl); 형태로 구현되어있고 
 comment.item.php 파일에 정의되어있다.
 질문) 내 회원정보를 보면 본 사람의 정보가 기록 
되고 해당 글쓴이는 포인트가 차감되도록 
 질문) 글이 스크랩되면, 해당 글쓴이에게 포인트가 
지급되게 하려면? 
 질문) 회원이 탈퇴하면 탈퇴내역을 남기고 해당 유 
저가 쓴 모든 글들이 삭제되게 하려면?
 1. trigger 장점 
 1) 특정 함수의 실행 중간에 외부 다른 모듈의 함수를 실행가능 
 2) 함수 실행과정에서 변하는 변수 값들을 외부함수에 
 바로 전달가능 
 3) 손쉽게 원하는 위치에 trigger 를 추가 정의 가능 
 2. Trigger 선언 
 함수내부에 $trigger_output = ModuleHandler::triggerCall(' 
모듈명.action', 'before/after', 전달할변수); 로 선언 
 (참고)Trigger 목록 - http://xpressengine.com/22556075
 3. Trigger 사용 방법 
 DB 의 module_trigger 라는 table 에 저장이 되어야함 
 해당 모듈의 class.php 파일에서 등록 
 checkUpdate()함수에서 if(!$oModuleModel->getTrigger 
 (‘트리거위치 모듈.함수’,’현재모듈’,’type’, ‘연결함수', 
'after/before')) return true; 로 확인하고 
 moduleUpdate() 함수에서 $oModuleController- 
>insertTrigger 
(‘트리거위치 모듈.함수’,’현재모듈’,’type’, ‘연결할함수', 
'after/before'); 등록 
 모듈 내부에, 연결할 함수를 해당 type 에 만들어두면 연결 됨
 4. 주의) 전달할 변수형태가 trigger 마다 모두 다르기에 
trigger 사용시 미리 확인을 해야함 
 글 추천후 실행되는 
ModuleHandler::triggerCall('document.updateVotedCou 
nt', 'after', $obj); 에서는 $obj 변수형태로 member_srl, 
document_srl, before_point, after_point 등이 전달 
 글 읽은 후 실행되는 
ModuleHandler::triggerCall('document.updateReadedCo 
unt', 'after', $oDocument); 에서는 $oDocument 가 전달. 
$oDocument->getMemberSrl() , $oDocument- 
>get('document_srl') 형태 등으로 사용
 활용예 1 ) 글 작성시 포인트 추가되는 과정 
 
글작성하면 insertDocument 함수 끝부분에 
 $trigger_output = 
ModuleHandler::triggerCall('document.insertDocument', 
'after', $obj); 를 통해 트리거를 호출하면 
 Point 모듈에, $oModuleController- 
>insertTrigger('document.insertDocument', 'point', 
'controller', 'triggerInsertDocument', 'after'); 로 선언된 
trigger 가 실행되어 
 Point.controller.php 의 triggerInsertDocument 함수가 실 
행되면서, 해당 글 작성에 따른 포인트가 지급
 활용예 2) 
 ‘이 게시글을’ , ‘이 댓글을’, ‘닉네임 클릭시 회원 관련 팝 
업’등도 전부 다 이 trigger 기반으로 구현되어있고, 
trigger 추가로 마이페이지 관리등이 가능 
 활용예 3 ) 인맥사이트 등에서 포인트 이용한 타인의 회원 
정보를 확인기능 등에.. 
 modules/member/member.view.php 의 
dispMemberInfo 함수에 새로운 triggerCall 을 추가로 정 
의 ( before 형태 ) 
 이 trigger 를 이용할 함수를 하나 정의해서 회원정보 확인 
위해 필요한 포인트가 있는지 여부 / 있으면 포인트 차감 / 
해당 회원에게는 방문자수 추가 및 포인트지급
 질문) 버튼클릭으로 ‘진행중’인 카테고리값이나 확 
장변수 값을 ‘진행완료’로 값을 변경하게 하려면? 
 질문) 첫번째 카테고리 를 선택하면 그 하위의 2 
차 카테고리가 옆에 selectbox로 뜨게 하려면? 
 질문) 특정값을 text 에 기입시 중복되지는 실시간 
으로 확인하게 하려면? (회원가입시 닉네임처럼)
 1. exec_json / exec_xml 장점 
 - 스킨이나 레이아웃에서 XE 함수들과 변수를 ajax 기반으로 구현 
해 바로 반응하도록 구현 지원 
 - ajax 를 아예 몰라도 사용 가능
 2. 내장형– doCallModuleAction - exec_xml기반 ( script) 
 1) doCallModuleAction(module, action, target_srl) 형태 
 세변수를 전달 - target_srl, cur_mid, mid 
 exec_xml(module, action, params, completeCallModuleAction); 
 해당 대상(target_srl) 에 대해 특정module의 특정action 을 실행 
 2) 리턴으로 completeCallModuleAction(ret_obj) 실행 
 실행 성공시 reload(), 실패시 alert 하는 구조이다. 
 3) 추천/비추천,스크랩,신고기능등 특정 srl에 대한 특정 module의 
action을 호출하는 함수 등에서 현재 사용중 
 (참고 : common/js/xe.js 에 정의되어있음)
 3. exec_xml ( Javascript 기반) 
 1) exec_xml('모듈명', '모듈action', params(전달할변수), 콜 
백함수, responses(리턴변수), 리턴함수params, fo_obj); 
 2) 모듈action 은 해당 modules.xml 에 정의 필요 
 3) params 는 array 도 되고, json 형식으로 써도 무관. 
Params 를 action 에서 Context::get('변수명') 형태로 받음 
 4) responses 는 배열로 정의를 해두고 (미리 정의 안 해두면 
사용불가), 해당 모듈action 에서, $this->add('콜백변수명', 
'콜백변수값'); 형태로 전달하면 콜백함수에서 사용가능 
 5) 콜백함수는, function callback(ret_obj) 형태로 정의해두 
고, 앞서 받은 ret_obj['콜백변수'] 형태로 사용가능
 4. jQuery.exec_json ( jQuery 기반) 
 사용법이 조금 더 단순하고, exec_xml 은 브라우저에 따라 에러 
나는 경우가 있어 exec_json 을 사용하는 추세 
 1) jQuery.exec_json(‘모듈명.action’,params,콜백함수,에러함수); 
 2) 모듈명과 action 을 한 항목에 한꺼번에 기재되는것이 차이 
3) params 변수 전달은 json 형태를 따라야한다. (배열불가) 
 예) var params = {'target_srl':target_srl,'cur_mid':current_mid}; 
4) 콜백함수에 전달할 response_tags 변수를 미리 정의하지 않 
아도 된다는 점이 exec_xml 과 다른 상당히 편한 부분이다
 5. 콜백변수에 반환데이터 
 하나의 row 로 된 데이터 뿐만 아니라, 여러 row 된 값의 반환까 
지도 전부 가능 
 1) 하나의 row 만 반환하는 경우 - executeQuery 
 $output = executeQuery('document.getDocument', $args); 
 $this->add("list", $output->data); 
 하나의 row 값만 전달한 경우에는, 콜백함수에서 
 function callback(ret_obj){ 
 var list = ret_obj['list']; 
 alert(list.document_srl); 
 }
 2) 복수개의 row 를 전달 – executeQueryArray => item 
 $output = executeQueryArray('document.getDocumentList', 
$args); 
 $this->add("list", $output->data); 
 복수개의 row 를 전달시 XE는 자동으로 item라는 항목을 만듬 
 function callback(ret_obj){ 
 var list = ret_obj['list']; 
 alert(list.item[0].document_srl); 
 alert(list.item[1].document_srl); 
 }
 아니면 전체를 for 문으로 돌려 사용할 수 있다 
 function callback(ret_obj){ 
 var list = ret_obj['list']; 
 for (var i in list.item){ alert(i + ' => ' + 
list.item[i]['document_srl']); } 
 } 
 이를 활용하면, 선택에 따라 목록리스트 추가출력 ( 더보기) 
이나 selectbox 연계 기능등을 구현할 수 있다.
 6. 예시) 추천버튼 클릭시 바로 추천수 반영되도록 
 <a onclick=“doCallModuleActionDocumentVote('document', 
'procDocumentVoteUp',{$oDocument->document_srl},’5’)”>추천 
<span class="num" id="document_voted_count">{$oDocument- 
>get('voted_count')}</span></a> 
 이 기능을 위해선 procDocumentVoteUp 함수를 조금 수정해야함 
 $point = 1; 대신 $point=Context::get(‘point’); 로 추천수 증가폭 설정 
 내부에서 실행되는 updateVotedCount 함수에 보면, 
 $output->add('voted_count', $obj->after_point); 로는 애드온에서 
 반응을 안 하고, 그밑에 $this->add('voted_count', $obj->after_point); 
형태로 추가
 1) exec_xml 로 구현 
 function doCallModuleActionDocumentVote(module, action, 
target_srl, point) { 
 var params = new Array(); 
 params['target_srl'] = target_srl; // 글번호 전달 
 params['cur_mid'] = current_mid; // 현재의 게시판 
 params[‘point'] = point; // 증가할 추천수 전달 
 var response_tags = ['error','message','voted_count']; // 
voted_count 받음 
 exec_xml(module, action, params, completeDocumentVote, 
response_tags); 
 }
 Voted_count 가 response_tags 에 정의가 미리 되어있기에 
add 된 이 값을 completeDocumentVote 에 전달이 가능하다 
 function completeDocumentVote(ret_obj, response_tags) { 
 var error = ret_obj.error; 
 var message = ret_obj.message; 
 var voted_count = ret_obj.voted_count; 
 if(!isNaN(parseInt(voted_count))) { 
 alert(voted_count+'번째로 추천'); 
 
jQuery('#document_voted_count').html(voted_count); 
 } 
 }
 2) exec_josn 으로 구현시에는 
 function doCallModuleActionDocumentVote(module, 
action, target_srl, point) { 
 var params = 
{'target_srl':target_srl,'cur_mid':current_mid, ‘point ': 
point}; 
 jQuery.exec_json(module+'.'+action, params, 
completeDocumentVote); 
 } 
만으로도 구현이 가능하다 
(Response_tags 변수가 아예 빠져있다.)
 질문) XE query xml 문법에서 지원 안 하는 
query 를 쓰고 싶을때는 어떻게 하나요?
 1, xml query 실행 – executeQuery() / executeQueryArray() 
 executeQuery 는 하나의 row 값만 받기 위한 용도 
 executeQueryArray 는 여러 row 로 된 list 형태를 받기 위한 용도 
( 리턴값이 stdClass 이기에 foreach로 접근해야 한다 ) 
 
그러나 실제적으로는, 이와 무관하게 xml 내부에 
<navigation>~</navigation> 부분이 있는지 여부에 따라 리턴 
되는 구조가 달라진다.
 2. executeQueryArray 와 xml query 의 장점 
 1) XE 만의 xml 형식의 query 를 통해 여러 DB 기반에서 작동 
 2) 다른 모듈등에서도 query 를 재정의할 필요없이 빌려 사용 가능 
 3) list 같이 여러 row 를 받는 경우, 자동으로 페이지구조 변수 
( $page_navigation )까지 자동 생성 
 4) 사용은 executeQuery(‘모듈명.query파일’,$변수,$칼럼) 형태 
 위젯의 경우는 ‘widgets.위젯명.query파일’, 
 애드온은 ‘addons.애드온명.query파일’
 3. XE 의 DB 활용위한 xml 의 한계 
 1) 가변적인 query 를 XE query 로는 구현이 어려움 
2) XE xml query 에서 지원하지 않는 query 구문들도 사용 가능 
( 예. LOWER(칼럼) / 복잡한 서브쿼리나 table join 등) 
3) 테이블, 칼럼생성/변경 등 table 자체의 변화를 주는 구현 난해 
4) XE Core 에 정의되어있는 DB Table 에 문자열 칼럼을 추가하 
면, schema 파일에 추가 선언이 없으면 insert/update 가 안 되 
는 문제 발생. Core update 문제 
 
5) page_navigation 기능이 필요없는 경우에도 불필요한 총 갯수 
구하는 query 가 실행됨. 속도 저하의 원인이 됨
 이를 보완하기 위해, $oDB 를 직접 사용 
 
$oDB = &DB::getInstance(); 
 ( classes/db/DB.class.php 에 정의) 
 $oDB->_query($query); // 쿼리 실행 
 ( class/db/DB.class.php ) 
 $oDB->_fetch($query); // 쿼리 결과 mysql_fetch_object 
 ( class/db/DBMysql.class.php )
 4. $oDB 를 이용해 query 구현하는 방법 
 $oDB = &DB::getInstance(); 
 $db_info = Context::getDBInfo(); 
 $prefix = $db_info->master_db["db_table_prefix"]; 
 $database = $db_info->master_db["db_database"]; 
 $query = " SELECT ~~~ "; // 가변적 query 
 $query .= “ WHERE document_srl = ".$args->document_srl “; 
 $qyery .= “ORDER BY ~~~”; 
 $query_query = $oDB->_query($query); 
 $result_query = $oDB->_fetch($query); 
 추후 이 $reulst_query 를 foreach 나 loop 로 돌리면 출력이 가능
 5. oDB 기반에서 page_navigation 변수 생성 방법 
 $oDB의 한계가 executeQuery와 달리, total_count 가 없기에 
$page_navagation 을 생성하지 않는다. 
 XE 에서 목록의 page_navigation 구조를 자동으로 만들어주는데, 
$oDB 에서도 이를 이용하면 된다. 
 $output->page_navigation = new PageHandler($total_count, 
$total_page, $page, $page_count); 
 ( classes/page/PageHandler.class.php ) 
 $total_count, $total_page 는 별도 query 로, $page 는 Context 로 
 현재페이지, $page_count 는 설정을 참고하거나 미리 정의
 우선 사용할 쿼리를 두개로 분리 한 후.. 
 $query_total = $query; // 총 개수 구하기 위한 용도 
 $query_limit = $query." LIMIT ".($page-1)*$list_count.",".$list_count; 
// 실제 사용할 쿼리 
 그 후 페이징에 필요한 값들 따로 구한 뒤 page_navigation 부터 구현 
 $query_total = $oDB->_query($query_total); 
 $output_total = $oDB->_fetch($query_total); 
 $output->total_count = $total_count = count($output_total); 
 $output->total_page = $total_page = (int)($output- 
>total_count/$list_count)+1; 
 $output->page = $page; 
 $output->page_navigation = new PageHandler($total_count, 
$total_page, $page, $page_count);
 그 후 실제 필요한 query 를 실행 
 $query_limit = $oDB->_query($query_limit); 
 $output_limit = $oDB->_fetch($query_limit); //실제 필요한 값 
 if(count($output_limit)==1) { 
 $no=1; 
 $output->data[$no] = $output_limit; 
 } 
 else { 
 foreach($output_limit as $key=>$val) { 
 $no = $total_count-(($page-1)*$list_count)-$key; 
 $output->data[$no] = $val; 
 } 
 } 
 return $output;
 이렇게 해서 $output 을 리턴하면 executeQueryArray 
와 동일한 형태의 결과가 리턴되기에 
 $output->data 
 $output->page_navagation 
 return $output; 
 스킨등에서 기존에 쓰던 형식 그대로 호환되어 사용이 
가능해진다.

Xe hack

  • 1.
  • 2.
     I. XE내장함수 사용방법  II. 모듈간의 연결 – Trigger  III. 실시간반응 – exec_xml/json  IV. 쿼리사용 - $oDB = &DB::getInstance();
  • 3.
     질문) 게시글에글쓴이 회원정보들이 나타나게 하 고 싶은데 어떻게 하나요?  질문) 글을 추천한 추천인 목록을 스킨에 출력하려 면 어떻게 해야하나요?  질문) 어떤 기능을 구현하려면 어딜 어떻게 고쳐야 하나요? 해당 페이지 파일은 어디에?
  • 4.
     1. 함수이름 규칙  1) Type + 모듈이름 + (Admin) + 고유이름  ( disp 는 view , proc 는 controller, get 은 model 파일에 있음.)  2) view 파일들은 해당 함수에 setTemplateFile(‘파일명’) 에 정의됨 ( 스킨 또는 tpl 내에 파일명.html 형태)  (getModel 등은 config/func.inc.php 에 정의되어있기에 XE 어디서나 사용가능)
  • 5.
     2. action미리 선언 - module.xml 미리 정의  1) Url로 Act 변수를 직접 사용 – 주로 view 관련 disp action ( 회원가입-dispMemberSignUpForm)  2) exec_xml 나 exec_json 등에서 사용하려는 경우  - 행위 반응 proc action ( procDocumentVoteUp )  - 목록 추출 disp action ( dispBoardContentList )  3) 각 모듈의 module.xml 에 정의를 해줘야 인식됨  <action name="dispMemberInfo" type="view“> (참고) index="true“ 는 해당 모듈에서 별도의 act 없을때 기본 실행함수  admin_index=“true” 는 관리자화면에서 기본act
  • 6.
     3. 필요한함수를 바로 선언해서 사용  1) getModel(‘모듈’)->함수, getController(‘모듈’)–>함수  getView(‘모듈’)->함수 형태로 사용  2) 함수별로 전달해야하는 변수값을 확인하고 받는 리턴값을 확인해서 사용  3) 함수들은 모듈, 애드온, 위젯뿐만 아니라,  레이아웃이나 스킨 등에서도 자유롭게 사용이 가능.  (스킨소스를 최대한 간편하게 하기 위해 모듈 내부에서 미리 선언해 변수 화한것 뿐)
  • 7.
     4. 예)게시판 스킨 view 에서, 작성자 정보 출력  {@  $oMemberModel = getModel('member');  $writer_info = $oMemberModel- >getMemberInfoByMemeberSrl($oDocument- >getMemberSrl());  }  닉네임 : {$oDocument->getNickName()} <br/>  이름 : {$oDocument->getUserName()} <br/>  연락처 : {str_replace('|@|','-',$writer_info->tel)} <br/>  주소 : {str_replace('|@|',' ',$writer_info->address)}
  • 8.
     5. 참고)$oDocument, $oComment  $oDocument 는 document_srl 값을 기준으로 글정보를 함 수화한 변수  $oDocument = $oDocumentModel- >getDocument($document_srl); 로 구해진 거고  이를 통해 사용가능한 함수들은 document.item.php 파일에 정의되어있다.  댓글도 마찬가지로  $oComment = $oCommentModel- >getComment($comment_srl); 형태로 구현되어있고  comment.item.php 파일에 정의되어있다.
  • 9.
     질문) 내회원정보를 보면 본 사람의 정보가 기록 되고 해당 글쓴이는 포인트가 차감되도록  질문) 글이 스크랩되면, 해당 글쓴이에게 포인트가 지급되게 하려면?  질문) 회원이 탈퇴하면 탈퇴내역을 남기고 해당 유 저가 쓴 모든 글들이 삭제되게 하려면?
  • 10.
     1. trigger장점  1) 특정 함수의 실행 중간에 외부 다른 모듈의 함수를 실행가능  2) 함수 실행과정에서 변하는 변수 값들을 외부함수에  바로 전달가능  3) 손쉽게 원하는 위치에 trigger 를 추가 정의 가능  2. Trigger 선언  함수내부에 $trigger_output = ModuleHandler::triggerCall(' 모듈명.action', 'before/after', 전달할변수); 로 선언  (참고)Trigger 목록 - http://xpressengine.com/22556075
  • 11.
     3. Trigger사용 방법  DB 의 module_trigger 라는 table 에 저장이 되어야함  해당 모듈의 class.php 파일에서 등록  checkUpdate()함수에서 if(!$oModuleModel->getTrigger  (‘트리거위치 모듈.함수’,’현재모듈’,’type’, ‘연결함수', 'after/before')) return true; 로 확인하고  moduleUpdate() 함수에서 $oModuleController- >insertTrigger (‘트리거위치 모듈.함수’,’현재모듈’,’type’, ‘연결할함수', 'after/before'); 등록  모듈 내부에, 연결할 함수를 해당 type 에 만들어두면 연결 됨
  • 12.
     4. 주의)전달할 변수형태가 trigger 마다 모두 다르기에 trigger 사용시 미리 확인을 해야함  글 추천후 실행되는 ModuleHandler::triggerCall('document.updateVotedCou nt', 'after', $obj); 에서는 $obj 변수형태로 member_srl, document_srl, before_point, after_point 등이 전달  글 읽은 후 실행되는 ModuleHandler::triggerCall('document.updateReadedCo unt', 'after', $oDocument); 에서는 $oDocument 가 전달. $oDocument->getMemberSrl() , $oDocument- >get('document_srl') 형태 등으로 사용
  • 13.
     활용예 1) 글 작성시 포인트 추가되는 과정  글작성하면 insertDocument 함수 끝부분에  $trigger_output = ModuleHandler::triggerCall('document.insertDocument', 'after', $obj); 를 통해 트리거를 호출하면  Point 모듈에, $oModuleController- >insertTrigger('document.insertDocument', 'point', 'controller', 'triggerInsertDocument', 'after'); 로 선언된 trigger 가 실행되어  Point.controller.php 의 triggerInsertDocument 함수가 실 행되면서, 해당 글 작성에 따른 포인트가 지급
  • 14.
     활용예 2)  ‘이 게시글을’ , ‘이 댓글을’, ‘닉네임 클릭시 회원 관련 팝 업’등도 전부 다 이 trigger 기반으로 구현되어있고, trigger 추가로 마이페이지 관리등이 가능  활용예 3 ) 인맥사이트 등에서 포인트 이용한 타인의 회원 정보를 확인기능 등에..  modules/member/member.view.php 의 dispMemberInfo 함수에 새로운 triggerCall 을 추가로 정 의 ( before 형태 )  이 trigger 를 이용할 함수를 하나 정의해서 회원정보 확인 위해 필요한 포인트가 있는지 여부 / 있으면 포인트 차감 / 해당 회원에게는 방문자수 추가 및 포인트지급
  • 15.
     질문) 버튼클릭으로‘진행중’인 카테고리값이나 확 장변수 값을 ‘진행완료’로 값을 변경하게 하려면?  질문) 첫번째 카테고리 를 선택하면 그 하위의 2 차 카테고리가 옆에 selectbox로 뜨게 하려면?  질문) 특정값을 text 에 기입시 중복되지는 실시간 으로 확인하게 하려면? (회원가입시 닉네임처럼)
  • 16.
     1. exec_json/ exec_xml 장점  - 스킨이나 레이아웃에서 XE 함수들과 변수를 ajax 기반으로 구현 해 바로 반응하도록 구현 지원  - ajax 를 아예 몰라도 사용 가능
  • 17.
     2. 내장형–doCallModuleAction - exec_xml기반 ( script)  1) doCallModuleAction(module, action, target_srl) 형태  세변수를 전달 - target_srl, cur_mid, mid  exec_xml(module, action, params, completeCallModuleAction);  해당 대상(target_srl) 에 대해 특정module의 특정action 을 실행  2) 리턴으로 completeCallModuleAction(ret_obj) 실행  실행 성공시 reload(), 실패시 alert 하는 구조이다.  3) 추천/비추천,스크랩,신고기능등 특정 srl에 대한 특정 module의 action을 호출하는 함수 등에서 현재 사용중  (참고 : common/js/xe.js 에 정의되어있음)
  • 18.
     3. exec_xml( Javascript 기반)  1) exec_xml('모듈명', '모듈action', params(전달할변수), 콜 백함수, responses(리턴변수), 리턴함수params, fo_obj);  2) 모듈action 은 해당 modules.xml 에 정의 필요  3) params 는 array 도 되고, json 형식으로 써도 무관. Params 를 action 에서 Context::get('변수명') 형태로 받음  4) responses 는 배열로 정의를 해두고 (미리 정의 안 해두면 사용불가), 해당 모듈action 에서, $this->add('콜백변수명', '콜백변수값'); 형태로 전달하면 콜백함수에서 사용가능  5) 콜백함수는, function callback(ret_obj) 형태로 정의해두 고, 앞서 받은 ret_obj['콜백변수'] 형태로 사용가능
  • 19.
     4. jQuery.exec_json( jQuery 기반)  사용법이 조금 더 단순하고, exec_xml 은 브라우저에 따라 에러 나는 경우가 있어 exec_json 을 사용하는 추세  1) jQuery.exec_json(‘모듈명.action’,params,콜백함수,에러함수);  2) 모듈명과 action 을 한 항목에 한꺼번에 기재되는것이 차이 3) params 변수 전달은 json 형태를 따라야한다. (배열불가)  예) var params = {'target_srl':target_srl,'cur_mid':current_mid}; 4) 콜백함수에 전달할 response_tags 변수를 미리 정의하지 않 아도 된다는 점이 exec_xml 과 다른 상당히 편한 부분이다
  • 20.
     5. 콜백변수에반환데이터  하나의 row 로 된 데이터 뿐만 아니라, 여러 row 된 값의 반환까 지도 전부 가능  1) 하나의 row 만 반환하는 경우 - executeQuery  $output = executeQuery('document.getDocument', $args);  $this->add("list", $output->data);  하나의 row 값만 전달한 경우에는, 콜백함수에서  function callback(ret_obj){  var list = ret_obj['list'];  alert(list.document_srl);  }
  • 21.
     2) 복수개의row 를 전달 – executeQueryArray => item  $output = executeQueryArray('document.getDocumentList', $args);  $this->add("list", $output->data);  복수개의 row 를 전달시 XE는 자동으로 item라는 항목을 만듬  function callback(ret_obj){  var list = ret_obj['list'];  alert(list.item[0].document_srl);  alert(list.item[1].document_srl);  }
  • 22.
     아니면 전체를for 문으로 돌려 사용할 수 있다  function callback(ret_obj){  var list = ret_obj['list'];  for (var i in list.item){ alert(i + ' => ' + list.item[i]['document_srl']); }  }  이를 활용하면, 선택에 따라 목록리스트 추가출력 ( 더보기) 이나 selectbox 연계 기능등을 구현할 수 있다.
  • 23.
     6. 예시)추천버튼 클릭시 바로 추천수 반영되도록  <a onclick=“doCallModuleActionDocumentVote('document', 'procDocumentVoteUp',{$oDocument->document_srl},’5’)”>추천 <span class="num" id="document_voted_count">{$oDocument- >get('voted_count')}</span></a>  이 기능을 위해선 procDocumentVoteUp 함수를 조금 수정해야함  $point = 1; 대신 $point=Context::get(‘point’); 로 추천수 증가폭 설정  내부에서 실행되는 updateVotedCount 함수에 보면,  $output->add('voted_count', $obj->after_point); 로는 애드온에서  반응을 안 하고, 그밑에 $this->add('voted_count', $obj->after_point); 형태로 추가
  • 24.
     1) exec_xml로 구현  function doCallModuleActionDocumentVote(module, action, target_srl, point) {  var params = new Array();  params['target_srl'] = target_srl; // 글번호 전달  params['cur_mid'] = current_mid; // 현재의 게시판  params[‘point'] = point; // 증가할 추천수 전달  var response_tags = ['error','message','voted_count']; // voted_count 받음  exec_xml(module, action, params, completeDocumentVote, response_tags);  }
  • 25.
     Voted_count 가response_tags 에 정의가 미리 되어있기에 add 된 이 값을 completeDocumentVote 에 전달이 가능하다  function completeDocumentVote(ret_obj, response_tags) {  var error = ret_obj.error;  var message = ret_obj.message;  var voted_count = ret_obj.voted_count;  if(!isNaN(parseInt(voted_count))) {  alert(voted_count+'번째로 추천');  jQuery('#document_voted_count').html(voted_count);  }  }
  • 26.
     2) exec_josn으로 구현시에는  function doCallModuleActionDocumentVote(module, action, target_srl, point) {  var params = {'target_srl':target_srl,'cur_mid':current_mid, ‘point ': point};  jQuery.exec_json(module+'.'+action, params, completeDocumentVote);  } 만으로도 구현이 가능하다 (Response_tags 변수가 아예 빠져있다.)
  • 27.
     질문) XEquery xml 문법에서 지원 안 하는 query 를 쓰고 싶을때는 어떻게 하나요?
  • 28.
     1, xmlquery 실행 – executeQuery() / executeQueryArray()  executeQuery 는 하나의 row 값만 받기 위한 용도  executeQueryArray 는 여러 row 로 된 list 형태를 받기 위한 용도 ( 리턴값이 stdClass 이기에 foreach로 접근해야 한다 )  그러나 실제적으로는, 이와 무관하게 xml 내부에 <navigation>~</navigation> 부분이 있는지 여부에 따라 리턴 되는 구조가 달라진다.
  • 29.
     2. executeQueryArray와 xml query 의 장점  1) XE 만의 xml 형식의 query 를 통해 여러 DB 기반에서 작동  2) 다른 모듈등에서도 query 를 재정의할 필요없이 빌려 사용 가능  3) list 같이 여러 row 를 받는 경우, 자동으로 페이지구조 변수 ( $page_navigation )까지 자동 생성  4) 사용은 executeQuery(‘모듈명.query파일’,$변수,$칼럼) 형태  위젯의 경우는 ‘widgets.위젯명.query파일’,  애드온은 ‘addons.애드온명.query파일’
  • 30.
     3. XE의 DB 활용위한 xml 의 한계  1) 가변적인 query 를 XE query 로는 구현이 어려움 2) XE xml query 에서 지원하지 않는 query 구문들도 사용 가능 ( 예. LOWER(칼럼) / 복잡한 서브쿼리나 table join 등) 3) 테이블, 칼럼생성/변경 등 table 자체의 변화를 주는 구현 난해 4) XE Core 에 정의되어있는 DB Table 에 문자열 칼럼을 추가하 면, schema 파일에 추가 선언이 없으면 insert/update 가 안 되 는 문제 발생. Core update 문제  5) page_navigation 기능이 필요없는 경우에도 불필요한 총 갯수 구하는 query 가 실행됨. 속도 저하의 원인이 됨
  • 31.
     이를 보완하기위해, $oDB 를 직접 사용  $oDB = &DB::getInstance();  ( classes/db/DB.class.php 에 정의)  $oDB->_query($query); // 쿼리 실행  ( class/db/DB.class.php )  $oDB->_fetch($query); // 쿼리 결과 mysql_fetch_object  ( class/db/DBMysql.class.php )
  • 32.
     4. $oDB를 이용해 query 구현하는 방법  $oDB = &DB::getInstance();  $db_info = Context::getDBInfo();  $prefix = $db_info->master_db["db_table_prefix"];  $database = $db_info->master_db["db_database"];  $query = " SELECT ~~~ "; // 가변적 query  $query .= “ WHERE document_srl = ".$args->document_srl “;  $qyery .= “ORDER BY ~~~”;  $query_query = $oDB->_query($query);  $result_query = $oDB->_fetch($query);  추후 이 $reulst_query 를 foreach 나 loop 로 돌리면 출력이 가능
  • 33.
     5. oDB기반에서 page_navigation 변수 생성 방법  $oDB의 한계가 executeQuery와 달리, total_count 가 없기에 $page_navagation 을 생성하지 않는다.  XE 에서 목록의 page_navigation 구조를 자동으로 만들어주는데, $oDB 에서도 이를 이용하면 된다.  $output->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count);  ( classes/page/PageHandler.class.php )  $total_count, $total_page 는 별도 query 로, $page 는 Context 로  현재페이지, $page_count 는 설정을 참고하거나 미리 정의
  • 34.
     우선 사용할쿼리를 두개로 분리 한 후..  $query_total = $query; // 총 개수 구하기 위한 용도  $query_limit = $query." LIMIT ".($page-1)*$list_count.",".$list_count; // 실제 사용할 쿼리  그 후 페이징에 필요한 값들 따로 구한 뒤 page_navigation 부터 구현  $query_total = $oDB->_query($query_total);  $output_total = $oDB->_fetch($query_total);  $output->total_count = $total_count = count($output_total);  $output->total_page = $total_page = (int)($output- >total_count/$list_count)+1;  $output->page = $page;  $output->page_navigation = new PageHandler($total_count, $total_page, $page, $page_count);
  • 35.
     그 후실제 필요한 query 를 실행  $query_limit = $oDB->_query($query_limit);  $output_limit = $oDB->_fetch($query_limit); //실제 필요한 값  if(count($output_limit)==1) {  $no=1;  $output->data[$no] = $output_limit;  }  else {  foreach($output_limit as $key=>$val) {  $no = $total_count-(($page-1)*$list_count)-$key;  $output->data[$no] = $val;  }  }  return $output;
  • 36.
     이렇게 해서$output 을 리턴하면 executeQueryArray 와 동일한 형태의 결과가 리턴되기에  $output->data  $output->page_navagation  return $output;  스킨등에서 기존에 쓰던 형식 그대로 호환되어 사용이 가능해진다.