XE 게시글 수정 화면에서 글 작성자 정보를 수정하는 란을 만들어보자

| 2014. 2. 27. 04:52

외주 작업에서 들어온 요청이었다. 기본적으로 글쓴이 개개인의 정보가 부각되는 웹사이트이고, 매번 글쓴이 본인이 자신의 아이디로 로그인을 해서 글을 올릴 수가 없는 구조였기 때문에 운영진 측에서 임의로 글을 올리고 그 글의 글쓴이를 다른 회원으로 수정할 수 있는 기능이 필요했다. 처음에는 아주 단순한 작업일 줄 알았다. 어딘가의 설정을 글쓴이 정보를 수정할 수 있게끔 바꾸면 되는 줄 알았다. 그러나 XE에서는 기본적으로 글쓴이 정보 수정 기능을 자체 플랫폼에서 제공하지 않고 있었다. 지난 포스팅과 흡사한 경우이긴 하나 ㅡ 즉 CMS에서 해결할 수는 없지만 DB단을 직접 건드리면 손쉽게 해결되는 일이라는 것 ㅡ 앞으로 이런 일이 빈번히 있을 것이라는 점, 그리고 수정 기능을 어떻게든 CMS 안으로 구겨넣어야 하고 일반인이 사용하기에 어렵지 않게 UX를 짜야 한다는 거대한 문제에 봉착하게 되었다.

난관에 봉착.

사실 알고리즘 자체는 단순한 작업이다. 문제는 XE의 코어를 최대한 건드리지 않으면서 어떻게 유지, 보수가 쉬운 코드를 쓰냐는 것이다. 논리적으로는 Document 모듈의 updateDocument() 따위의 메소드를 수정하는 것이 올바른 접근법이겠으나, Document 같이 사방에 엮여 있는 모듈의 코드들을 수정하기보다는 Board 모듈에 번외적인 기능으로서 글쓴이 정보 수정 기능을 넣는 것이 더 효율적인 접근법이라 여겨졌다. 작업의 범위를 정하고 다음의 요소를 고려하고, 코어 소스를 까보기 시작했다.

1. 글쓴이를 수정할 수 있는 페이지는 글 수정(=신규 작성) 페이지로 정했다. XE의 테이블 구조를 봤을 때 일단 A의 아이디로 글을 올린 뒤 글쓴이 정보만 B로 바꿨을 때 발생하는 문제점이 없기 때문이 1번, 실수를 하더라도 다시 바꿀 수 있는 여지가 계속 남아 있기 때문이 2번이었다.

2. 글 수정 화면 최하단에 텍스트 인풋 폼을 만들어 현재 글쓴이의 닉네임을 값으로 넣어두기로 했다. 글을 수정하는 사람이 아무런 수정을 하지 않으면 그대로 상태가 유지되고, 다른 회원의 닉네임을 입력하고 수정을 하면 그 글의 글쓴이 정보가 수정이 되되, 회원 레코드에 없는 닉네임을 입력했을 때는 수정이 되지 않게끔 했다. 사실 일반 유저에게 친화적이지 않은 회원 고유 ID 같은 값을 기준으로 했다면 말 그대로 뚝딱뚝딱 작업을 했을 것이지만 글 수정 기능을 사용하는 사람의 전문성을 고려하여 휴먼 프렌들리한 닉네임 값을 기준으로 삼았다.

우선은 보드 스킨에서 글쓴이 수정란을 추가하는 것이 필요하다. 자신이 사용하는 스킨의 write_form.html(모든 스킨의 글 작성, 수정 화면 관련 HTML 파일 이름이 이것인지는 잘 모르겠다.) 어딘가에 대충 아래와 비슷한 코드를 삽입해보자. 물론 기본적으로 XE가 새롭게 추가된 값을 인식할 수 있게끔 정해진 폼을 벗어난 곳에 코드를 넣으면 백날 수정해봐야 달라지는 것이 없을 것이다.

글쓴이 nick_name(글쓴이 수정시에만 변경, 글 작성시에는 공란):

다음은 보드 모듈을 수정할 차례다. XE에서 보드에 속한 Document의 정보를 수정하는 것은 modules/board/board.controller.php의 procBoardInsertDocument() 메소드에서 담당한다. 메소드 이름만 보면 글을 삽입하는 것 같아 보이지만 내부를 보면 조건문을 타고 글 수정의 기능을 겸비하고 있음을 알 수 있다. 글 수정 분기를 탄 곳의 제일 마지막에 아래와 같은 코드를 넣어보았다. 굳이 가장 아래에 코드를 넣은 이유는 Document 컨트롤러의 updateDocument()라는 메소드에서 무슨 일을 하는지는 모르나, 어쨌든 기존의 수정 과정이 끝난 뒤 글쓴이 정보를 수정하는 것이 여러모로 작업량을 줄여줄 수 있는 가능성이 크기 때문이었다.

if($this->grant->manager && $obj->modified_nick_name && $oDocument->getNickName() != $obj->modified_nick_name) {

	// get user info by modified_nick_name
	$temp_args = new stdClass();
	$temp_args->nick_name = $obj->modified_nick_name;
	$new_author_info = executeQuery('board.getMemberByNickname', $temp_args);
	if (!$new_author_info->data) {
		return new Object(-1,'msg_not_permitted');
	}

	// assign necessary variables to update the document
	$temp_args->user_id = $new_author_info->data->user_id;
	$temp_args->user_name = $new_author_info->data->user_name;
	$temp_args->member_srl = $new_author_info->data->member_srl;
	$temp_args->email_address = $new_author_info->data->email_address;
	$temp_args->homepage = $new_author_info->data->homepage;
	$temp_args->document_srl = $obj->document_srl;

	// update document info
	$update_author_member = executeQuery('board.updateAuthorInfo', $temp_args);
	if (!$update_author_member->toBool()) {
		return new Object(-1,'msg_not_permitted');
	}
}

그렇게 만족스러운 코드는 아니지만 대충 저렇다. 뭔가 일이 정상적으로 진행되지 않았을 때 알럿 창으로 뜨는 메시지의 경우, 그냥 기존의 메시지를 활용했는데 굳이 다른 메시지를 따로 만들어 넣기도 귀찮거니와 타이핑에 오타를 낸 경우 정도만 막아주면 웬만한 인풋에 대응이 가능한 상황이기 때문이다. 애를 먹었던 부분은 XE 쿼리의 반환값이 항상 반환된 객체의 data 객체 안으로 들어간다는 점, 그리고 executeQuery() 함수는 인자로 객체만을 받는다는 점 정도인 것 같다.

위 코드에서 사용된 두 가지 쿼리는 모두 직접 만들어야만 했다. XML 쿼리를 이렇게 직접 만들어본 것은 처음이었는데 결과물을 보면 알겠지만 그다지 어려운 일은 아니다. (티스토리에서 XML 태그를 너무 바보 같이 변환하는 바람에 SyntaxHighlighter로 표현하는 것이 불가능하다. 아래의 글은 각각의 쿼리에 대한 설명이었는데 써놓고 지우기엔 아깝고 해서 저렇게 줄을 긋고 내버려두겠다.)

괴상하게도 회원 정보를 닉네임으로 검색해서 불러오는 쿼리는 기본으로 없더라. 그래서 아주 간단한 쿼리를 만들 수밖에 없었다.

역시나 별 것 없고 해당 Document를 찾아 새롭게 입력된 회원 닉네임을 기반으로 한 정보를 업데이트 시켜주는 쿼리다. 사실 가장 마지막 문제는 이 쿼리의 작동 여부에 있었는데 ㅡ 그도 그럴 것이 PHP 단에서도 이 쿼리의 수행이 가장 마지막에 있다 ㅡ 어처구니 없게도 테이블 이름을 documents가 아닌 document로 잘못 입력했기 때문에 계속해서 원하는 결과를 얻지 못했더랬다. 회원의 경우엔 xe_member 테이블이면서 Document는 또 테이블 이름을 복수로 쓰다니, 굉장히 불만스러운 부분이었지만 아마 XE 팀도 나와 같은 생각을 하고 있겠지. 다만 아주 핵심적인 테이블들이기 때문에 그 이름을 함부로 고치는 것 또한 어려운 일이겠지.

정리하면, XE라는 CMS의 가능성과 한계를 동시에 볼 수 있는 작업이었다. 워드프레스에서는 아주 기본적으로 제공하고 있는 기능을 사용자가 직접 이렇게 품을 들여 만들어야 한다는 것이 여전히 한국용 CMS라는 인상을 강하게 남겼지만, 그럼에도 그렇게 많지 않은 노동량으로 쉽게 기능을 구현할 수 있다는 것에서 타이트하게 잘 짜여진 CMS라는 것을 느낄 수 있었다.

조금씩 XE에 익숙해져가고 있다. 실력이 늘어가는 것이 몸으로 느껴질 정도다.