Giter VIP home page Giter VIP logo

rx-module-exam's Introduction

rx-module-exam

XE 시험 모듈의 포크 버전

develop 브랜치

develop 브랜치를 clone하시는것은 권장하지 않습니다. git clone으로 사용시 main 브랜치를 clone하시는것을 권장합니다.

rx-module-exam's People

Contributors

yjsoft avatar cydemo avatar mend-bolt-for-github[bot] avatar

Stargazers

 avatar  avatar

Watchers

James Cloos avatar  avatar  avatar

Forkers

huhani cydemo

rx-module-exam's Issues

모바일 최적화

  • 모바일 스킨 제작
  • 접속이 끊겼을 경우를 대비한 임시저장 기능(시간제한 시험은 임시저장 불가)
  • 오프라인 상태일때 오프라인 상태임을 표시
  • 시간제한 시험을 모바일로 접속시 경고 메세지 표시

문제 출제에서 소제목 또는 공통지문 기능 문의

보셨는지 모르겠지만 이런 기능 요청이 있었는데요.
https://xetown.com/topics/1407214#comment_1407749

생각해보니 소제목 넣는 것 외에도 문제들간에 공통 지문이 쓰일 경우도 있을 것 같아서 요긴한 기능이라는 생각이 들었습니다.

현재 생각으로는 exam_question 테이블의 status 칼럼을 이용해서 문제 출제시에 소제목 또는 공통지문 형식으로 데이터를 등록해도 괜찮겠다는 소견입니다. 물론 자체 question_srl을 가지는 것으로요.
(한 가지 걸리는 것은 룰셋 검증을 거치는 것인데 js로 필수값을 대강 입력해주면 될 듯도 하구요.)

살펴보니 해당 테이블의 status 칼럼이 비밀 문제를 판별하는 변수로 보이는데요. 실제로는 사용하지 않는 기능이나 마찬가지더라구요. 공개/비밀로 노출을 결정하는 건 시험지 자체에서 처리하는 것으로 족할 것 같구요.

그래서 status 칼럼을 가지고 해당 기능을 추가해도 무방할지 의견 여쭙고자 합니다. 혹시라도 따로 복안이 있으시면 다른 방도를 구해봐야 할 것 같아서요.

오류 메시지 출력 통일

현재 오류 메시지 출력이 이중적 체계로 이뤄져 있습니다.
exam.admin.model.php와 exam.controller.php에서는 makeObject 함수를 사용하고 있고,
exam.view.php에서는 dispExamMessage라는 별도의 함수를 통해 스킨의 message.html 템플릿 파일을 컴파일하도록 되어 있습니다.
예. https://dev.aporia.blog/exam_21235 에서 '응시' 버튼 눌렀을 때와 '시험지 생성' 버튼 눌렀을 때

사이트 전체적인 통일성을 위해 exam.view.php에서도 makeObject 함수를 사용하는 것이 더 좋을 것 같습니다.

  • dispExamMessage 함수를 쓰면 makeObject 함수로 연결시키거나
  • dispExamMessage 함수 자체를 삭제하고, 해당 함수를 사용하는 부분을 makeObject로 대체하면 될 것 같습니다.

그렇게 하면, 사이트 전체에 통일감을 줄 수 있고, 스킨 작업에서도 message.html 파일을 삭제함으로써 스킨의 체계를 간소화하고 작업량도 줄일 수 있을 것 같습니다.

채점결과 설명의 어려움

조금더 친화적으로 바꾸면 어떨런지 모르겠습니다.

비공개 점수 공개 풀이 공개 전체 공개
시험 응시 후 결과를 어떻게 알려줄 것인지 선택할 수 있습니다. 비공개를 설정하면 응시자는 결과를 확인할 수 없으며 전체 공개로 설정하시면 정답까지 보여줍니다.

: 솔직히 채점결과를 알려주지 않는 경우가 있어야 하는지 이해가 잘 안됩니다. 시험지 결과는 확인이 언제나 가능 해야 할듯 합니다.

문제출제 및 수정에서 '지문'의 '머리글'이 전달되지 않는 문제 수정

exam.controller.php 파일
#245행
$args->description_title = htmlspecialchars($params->description_title, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
에서처럼 파라미터값이 잘못 코드화되어 있었습니다.

$args->description_title = htmlspecialchars($params->q_description_title, ENT_COMPAT | ENT_HTML401, 'UTF-8', false);
으로 고쳤더니 DB에 입력도 잘 되고 스킨 상에서도 잘 출력됩니다.

근데 이거 그냥 $args->description_title = escape($params->q_description_title); 으로 간소화해도 되지 않나요? 아... XE에선 안 되던가요;;;

시험 응시 현황에서 search_status 전달 오류 수정

'시험 응시 현황'(act=disExamMyResult)을 보면 합격/불합격 리스트만 따로 가져올 수 있도록 search_status를 파라미터로 넘겨줍니다.
(기존 스킨에서는 이걸 검색폼 형태로 넘겨주고 있는데ㅜㅜ 그냥 getUrl() 함수에 쿼리를 넘겨주는 링크 작업으로 대체 중입니다)

다만, 라이믹스 1.9.9.6 디벨롭 버전(2020-04-27) 기준으로 리스트 선별 취득에 실패하고 있었습니다.
disExamMyResult 함수(463행)에 있는 $args->status = Context::get('search_status'); 에서는 값이 잘 전달되고 있었는데요.
문제는 $args를 받고 있는 exam.model.php의 getExamResultList() 함수더군요.
여기 함수를 보면 lang.xml에서 $statusList 변수를 가져와서 파라미터값을 검증해서 잘못된 값이면 unset 시키는 부분이 있는데, $statusList가 ArrayObject여서인지 private이 걸려 있어서인지 array_key_exists 함수가 아예 안 먹히고 있었습니다.
즉, 353행 if(!array_key_exists(strtoupper($obj->status),$statusList)) unset($obj->status); 에서 무조건 false만 반환해서 status 값이 사라집니다.

그래서 이 부분을
if ( !isset($statusList[strtoupper($obj->status)]) ) unset($obj->status);
으로 수정했더니 status에 해당하는 search_status 파라미터가 잘 전달이 되어 스킨에서도 무사히 출력되는 것을 확인할 수 있었습니다.

getAllQuestionPoint 함수 수정

exam.item.php에서 총 배점이 0일 경우 100으로 출력하도록 되어 있습니다.
각 문제에 배점이 하나도 배정되어 있지 않거나, total_point 계산에 실패했을 경우에 0점이 됩니다.
이것을 굳이 100점으로 표시할 이유는 없어 보입니다.
뿐만 아니라 경우에 따라 100점 만점이 아닌 경우도 있기 때문에 100점으로 고정하는 것은 더욱 더 필요가 없어보입니다.

exam.item.php 566행
return $this->get('total_point') == 0 ? 100 : $this->get('total_point');
대신에
return $this->get('total_point');
으로 바로 출력값을 가져오는 것이 타당해보입니다.

라이믹스의 '짧은 주소' > '모든 주소 형태를 사용' 옵션에 대응

라이믹스의 '짧은 주소' > '모든 주소 형태를 사용' 옵션을 사용하면
Context::get('document_srl')을 인식하지 못해 시험지가 열리지 않는 문제가 있습니다.

module.xml 22행을 다음과 같이 바꿔서 이 문제에 대응할 수 있었습니다.

		<action name="dispExamIndex" type="view" index="true">
			<route route="$document_srl:int" priority="100" />
		</action>

단, XE나 라이믹스 2.x 미만에서는 테스트해보지 못했습니다.
어쨌든 라이믹스의 라우터 기능에 대응해서 해당 파일의 소스를 일부 업데이트하는 것이 필요하다고 생각합니다.

개발 재개 일정 안내

현재 본업으로 매우 바쁜 상태라... 9월 말쯤 일정이 정리되는대로 작업 재개 예정입니다.

문제 삭제시 해당 문제의 배점만큼 총 배점도 감산

현재는 시험 문제를 삭제할 때 해당 문제의 배점(point)만큼 시험의 총배점(total_point)이 감소되지 않고 있습니다.

procExamQuestionDelete() 함수를 개선할 필요가 있겠습니다.

exam.controller.php #328-329 행의
$output = $this->deleteQuestion($args);
if(!$output->toBool()) return $output;

윗부분을 다음과 같이 바꾸니 total_point도 수정되고 캐시 삭제로 바뀐 값도 바로 적용됩니다.

	$output = $this->deleteQuestion($args);
	if(!$output->toBool()) return $this->makeObject(-1, "msg_invalid_request");

	// 삭제한 문제의 배점만큼 만점 재계산
	$total_point = $examitem->get('total_point') - $questionitem->get('point');
	$output = $this->updateTotalPoint($document_srl, $total_point);
	if(!$output->toBool()) return $this->makeObject(-1, "Failed to update total_point");

	//remove from cache
	$oCacheHandler = CacheHandler::getInstance('object');
	if($oCacheHandler->isSupport())
	{
		//remove document item from cache
		$cache_key = 'exam_item:'. getNumberingPath($document_srl) . $document_srl;
		$oCacheHandler->delete($cache_key);
	}

문제 불러오기 기능을 위한 액션, 함수, 쿼리 추가

문제 출제 및 수정 시에 exec_json으로 기존의 시험문제를 불러올 수 있는 기능을 고안해봤습니다.
기본적으로는 1-1) 작동 중인 모듈의 모듈번호 기준으로 문제를 가져오고, 1-2) 모듈번호 인자를 전달하지 않으면 모든 시험문제를 리스트로 가져와서, 2) 문제를 선택한 뒤 출제 및 수정 폼 필드들에 덮어쓰는 방식입니다.
다음과 같이 액션, 함수, 쿼리를 추가해봤습니다.
살펴봐주셨으면 합니다~

  1. module.xml 에 액션 추가
    <action name="getQuestions" type="model" />

  2. exam.model.php 에 함수 추가

/**
 * 모듈 내의 모든 문제를 구함
 * @param int $module_srl
 * @return object
 */
function getQuestions($module_srl = 0, $status = 'Y')
{
	// get a list of questions
	$args = new stdClass;
	$args->module_srl = $module_srl ? $module_srl : Context::get('module_srl');
	if ( !Context::get('grant')->manager ) $args->status = $status ? $status : Context::get('status');
	$output = executeQueryArray('exam.getQuestions', $args);

	// return if an error occurs in the query results
	if ( !$output->toBool() ) return;

	$this->add('question_list', $output->data);
	return $output->data;
}
  1. getQuestions 쿼리 xml 추가
<query id="getQuestions" action="select">
    <tables>
        <table name="exam_question" alias="question" />
        <table name="exam" alias="exam" />
    </tables>
    <columns>
        <column name="question.*" />
        <column name="exam.title" alias="document_title" />
	<query id="getCategoryTitle" alias="category_title">
		<tables>
			<table name="document_categories" alias="category" />
		</tables>
		<columns>
			<column name="category.title" />
		</columns>
		<conditions>
			<condition operation="equal" column="category.category_srl" default="exam.category_srl" />
		</conditions>
	</query>
    </columns>
    <conditions>
        <condition operation="equal" column="question.module_srl" var="module_srl" filter="number" pipe="and" />
	<condition operation="equal" column="exam.document_srl" var="question.document_srl" notnull="notnull" pipe="and" />
        <condition operation="equal" column="question.status" var="status" pipe="and" />
    </conditions>
    <navigation>
		<index var="question.list_order" default="question.list_order" order="ASC" />
    </navigation>
</query>

문제 출제/수정에서 정답 지정시 jQuery 이벤트 수정

객관식 문제를 출제하거나 수정할 때 번호를 클릭하면 원형문자가 붉은색으로 변하고 해당번호는 정답으로 지정됩니다.
이때 이벤트 처리에서 e.preventDefault()를 추가해줘서 클릭시 스크롤이 document 최상단으로 움직이는 것을 방지해야 합니다.

./modules/exam/tpl/js/exam_admin.js 30행에 해당 구문을 추가하는 것이 좋겠습니다.
e.preventDefault();

빈 시험지에 문제 출제시 총 배점 가산이 안 되는 문제

빈 시험지에 문제를 새로 출제할 경우 총 배점으로 가산되지 않는 문제가 있습니다.
총 배점을 문제 리스트를 루프 돌려서 각 문제별로 point를 누적 가산시켜서 total_point를 구해오는데,
문제 리스트가 부재하는 경우에는 total_point의 초기값인 0이 그대로 반영되기 때문으로 이해됩니다.

exam.controller.php #276-281행이 이렇게 되어 있는데요.

		$total_point = 0;
		$question_list = $oExamModel->getQuestionList($document_srl);
		foreach($question_list->data as $key => $val)
		{
			$total_point += $val->point;
		}

다음과 같이 바꿀 것을 제안합니다.

		$total_point = 0;
		$question_list = $oExamModel->getQuestionList($document_srl);
		if ( count($question_list) )
		{
			foreach($question_list->data as $key => $val)
			{
				$total_point += $val->point;
			}
		}
		else
		{
			$total_point += $args->point;
		}

수동 채점 기능

서술형 문제 등 정답을 정해두기 애매한 경우 출제자가 직접 확인후 채점할수 있도록 구현
이외 객관식의 경우도 상황에 따라 정답처리할수 있도록 구현

추천/비추천시 포인트 차감

시험지가 추천을 받으면 포인트를 얻고, 비추천을 받으면 포인트를 잃음
시험지 추천/비추천으로 얻을수 있는 포인트 제한 구현

객관식 답안 여러개 체크 시 체점이 제대로 이루어지지 않음

  1. 문제 답안을 기준으로 응시자에 정답이 맞는지에 갯수를 체크함.
  2. 틀린 답이 있을 경우 무조건 오답처리를 해야 하지만 오답 체크를 하지 않음
  3. 모든 객관식 답안을 정답으로 제출할 경우 정답으로 인식함.

exam.controller.php 파일 수정 필요

		// 객관식이고 복수정답일때 처리
		if(!$qitem->getQType() && $q_answer_count>1)
		{
			$answer_list = explode(",", $answer);
			$q_answer_list = $qitem->getAnswerList();
			$answer_check_type = $qitem->get('answer_check_type');
			// 모두일치하면 정답+부분점수(기본배점/맞은갯수)
			if($answer_check_type==2)
			{
				$cnt = 0;
				foreach($answer_list as $key => $val)
				{
					if(in_array($val, $q_answer_list))
					{
						$cnt++;
					}else{				
						$cnt = 0;
						break;
					}
				}
				if($cnt) {
					if($cnt==$q_answer_count) $check = 'O';
					else $check = 'P';
				}
			} elseif($answer_check_type==1) // 모두일치하면 정답
			{
				$cnt = 0;
				foreach($answer_list as $key => $val)
				{
					if(in_array($val, $q_answer_list))
					{
						$cnt++;
					}else{
						$cnt= 0 ;
						break;
						}
				}
				if($cnt==$q_answer_count) $check = 'O';
			} else { // 하나만 일치해도 정답.
				foreach($answer_list as $key => $val)
				{
					if(!in_array($val, $q_answer_list))
					{
						$check = 'X';
						break;
					}else{
						$check = 'O';
					      }
				}
			}
		} else { // 복수 정답이 아닐때..

시험지 업데이트시 재응시 관련 안내

출제자는 시험지 업데이트는 가능한 반면에

응시자는 시험을 1번 치루고 나서는 시험지가 업데이트되더라도 일괄 재응시가 불가능합니다.

가장 좋은건 변경된 문제로만 재 응시 하여 전체 채점 결과가 변동이 되는 것일 것 같습니다.

의견 적어 봅니다.

감사합니다.

출제자 회원 정보가 나왔으면 합니다.

즉, 출제자가 누구인지 알수 있어야 할듯 합니다.

  1. 출제자의 동기부여 문제도 있지만
  2. 출제 문제에 따라 회원 제제도 필요한 경우도 생길수 있다고 생각합니다. (상습적인 불량 질문 시험지 작성등..)

문제 순서 변경을 위한 함수 및 액션 추가

중요한 기능 중에 하나가 시험지의 출제 문제 순서 변경이라고 생각합니다.

그래서 스킨에서 문제의 순서를 바꾸려고 시도를 해봤는데,
인접한 두 문제의 question_srl과 list_order를 놔두고 나머지 칼럼 데이터를 바꿔치기 하는 것말고는 별다른 방도가 없을 것 같습니다.
게시판 모듈의 확장변수처럼 document_srl을 공유하는 문항들에 idx를 별도 칼럼으로 두는 것도 좋겠지만, 그 또한 스키마 변경 및 그에 따르는 작업량이 만만치 않을 것 같더라구요ㅜ

그래서 문제의 순서를 변경할 수 있는 exam.controller.php에 별도의 함수를 작성하고 module.xml에도 관련 액션을 추가해서, 스킨단에서 exec_json으로 해당 기능을 구현해봤습니다.

exam.controller.php의 354행쯤부터...

/**
 * @brief 시험지에 문제 순서 변경 처리
 */
public function procExamQuestionSwap()
{
	// 권한 체크
	if ( $this->module_info->module !== 'exam' ) return $this->makeObject(-1, 'msg_invalid_request');
	if ( !$this->grant->create ) return $this->makeObject(-1, 'msg_not_permitted');
	$oExamModel = getModel('exam');

	// 선택된 문제 번호로 php 변수에 데이터 담아두기
	$selected_srl = Context::get('selected_srl');
	$selected_item = $oExamModel->getQuestion($selected_srl);

	// 표적화된 문제번호로 php 변수에 데이터 담아두기
	$targeted_srl = Context::get('targeted_srl');
	$targeted_item = $oExamModel->getQuestion($targeted_srl);

	// 선택 문제에 표적 문제의 데이터를 이전
	$args = new StdClass;
	$args->question_srl = $selected_srl;
	$args->question_level = $targeted_item->get('question_level');
	$args->question_type = $targeted_item->get('question_type');
	$args->title = $targeted_item->get('title');
	$args->content = $targeted_item->get('content');
	$args->answer = $targeted_item->get('answer');
	for ( $i = 1; $i <= 5; $i++ )
	{
		$args->{'answer'.$i} = $targeted_item->get('answer'.$i);
	}
	$args->answer_check_type = $targeted_item->get('answer_check_type');
	$args->use_description = $targeted_item->get('use_description');
	$args->description_title = $targeted_item->get('description_title');
	$args->description = $targeted_item->get('description');
	$args->regdate = $targeted_item->get('regdate');
	$args->ipaddress = $targeted_item->get('ipaddress');
	$args->status = $targeted_item->get('status');
	$args->point = $targeted_item->get('point');
	$output = $this->updateQuestion($args);

	// 표적 문제에 선택 문제의 데이터를 이전
	$args = new StdClass;
	$args->question_srl = $targeted_srl;
	$args->question_level = $selected_item->get('question_level');
	$args->question_type = $selected_item->get('question_type');
	$args->title = $selected_item->get('title');
	$args->content = $selected_item->get('content');
	$args->answer = $selected_item->get('answer');
	for ( $i = 1; $i <= 5; $i++ )
	{
		$args->{'answer'.$i} = $selected_item->get('answer'.$i);
	}
	$args->answer_check_type = $selected_item->get('answer_check_type');
	$args->use_description = $selected_item->get('use_description');
	$args->description_title = $selected_item->get('description_title');
	$args->description = $selected_item->get('description');
	$args->regdate = $selected_item->get('regdate');
	$args->ipaddress = $selected_item->get('ipaddress');
	$args->status = $selected_item->get('status');
	$args->point = $selected_item->get('point');
	$output = $this->updateQuestion($args);
}

그리고 module.xml의 35행쯤에
<action name="procExamQuestionSwap" type="controller" />

등을 추가했습니다.
문항 순서 변경을 위해 급하게 짜긴 했는데요.
일단 스킨단에서 무리없이 받아서 순서를 변경하는 데에는 성공할 수 있었습니다.

in_array 인자가 잘못 지정됨

기능상 영향은 없는 것 같은데요. 그래도 라이믹스에서 에러메시지 출력이 눈에 밟혀서ㅜ 제보 및 수정 상황 공유합니다.
모듈 설정 화면(dispExamAdminInsert)에서 디버그 패널을 참고했습니다...

  1. exam.controller.php #26행
    $extra_vars[$key] = new ExtraItem($module_srl, -1, in_array($key,'user_name','nick_name') ? Context::getLang('exam_writer') . " " . Context::getLang($key) : Context::getLang($key), $key, 'N', 'N', 'N', null);
    => $extra_vars[$key] = new ExtraItem($module_srl, -1, in_array($key, array('user_name','nick_name')) ? Context::getLang('exam_writer') . " " . Context::getLang($key) : Context::getLang($key), $key, 'N', 'N', 'N', null);
    으로 수정했습니다.

  2. tpl/exam_insert.html #233행
    <input type="checkbox" name="exam_pass_group_list[]" value="{$key}" id="group_{$key}" checked="checked"|cond="in_array($key,$module_info->exam_pass_group_list)" />
    => <input type="checkbox" name="exam_pass_group_list[]" value="{$key}" id="group_{$key}" checked="checked"|cond="is_array($module_info->exam_pass_group_list) && in_array($key,$module_info->exam_pass_group_list)" />
    으로 수정했습니다.

시험지 출제시 포인트 차감 기능

  1. 게시판도 그렇듯 글쓰기시에 포인트 설정을 할수 있습니다.

마찬가지 시험지 생성시에

포인트 차감이 가능하도록 하고 더 나아가 표시도 가능하면 동기부여에 좋을듯 합니다.

  1. 다만 위와 같이 하면 1문제 + 스팸성 시험문제만 제출 하고 포인트 먹튀가 가능하니
    추천/비추천을 통해 포인트 차감도 가능하였으면 합니다.

감사합니다.

문제번호 랜덤기능

온라인으로 하는 시험이다보니 볼때마다 문제순서가 바꾸는 기능이 있으면 좋겠네요.

시험기간 출력 방식 간소화

자꾸 올려서 죄송합니다. 바쁘실 텐데ㅜㅜ
스킨 작업을 하다보니까 눈에 들어오는 것들이 있어서요.

현재 스킨에서 '시험기간'은 exam.item.php 355행의 getExamDate($format = 'Y.m.d H:i') 함수를 받아서 출력하는 걸로 되어 있는데요.
이 부분이 너무 깁니다.
2020.05.15 12:00 ~ 2020.05.15 13:00 이런 식으로요.
이용자 입장에서는 시험지 목록에서 시험기간이 표시항목으로 있을 경우 기간 식별이 어렵고 시각적 피로감마저 느낄 수 있습니다.
그래서 이 부분을 2020.05.15 12시 ~ 13시 같은 식으로 줄여서 출력하면 어떨까 하는 생각이 들었습니다.

시작일시와 종료일시의 문자열을 비교해서 중복되는 형식을 생략해서
날짜 표기를 간소화하도록 getExamDate() 함수를 아래와 같이 수정하면 어떨까 합니다.

function getExamDate()
{
	if ( !$this->isDate() )
	{
		$str = Context::getLang('exam_no_end_date');
	}
	else
	{
		$start_date = $this->get('start_date');
		$end_date = $this->get('end_date');
		// 조건 설정 : 시작과 종료의 년도가 현재 년도와 같은지
		$this_year = substr($start_date, 0, 4) === date('Y') && substr($end_date, 0, 4) === date('Y');

		// 시작과 종료 모두 H시 정각이라면
		if ( substr($start_date, 10, 2) === '00' && substr($end_date, 10, 2) === '00' )
		{
			// 시작 시각은 시까지만 출력
			$startline = $this_year ? zdate($start_date, 'm.d H시'): zdate($start_date, 'Y.m.d H시');
			$str = $startline . ' ~ ';
			// 시작과 종료가 같은 시각이라면
			if ( substr($start_date, 0, 10) === substr($end_date, 0, 10) ) $str = $startline;
			// 일자까지 같다면
			elseif ( substr($start_date, 0, 8) === substr($end_date, 0, 8) ) $str .= zdate($end_date, 'H시');
			// 년도만 같다면
			else if ( substr($startline, 0, 4) === substr($end_date, 0, 4) ) $str .= zdate($end_date, 'm.d H시');
			// 년도가 다르다면
			else $str .= $this_year ? zdate($end_date, 'm.d. H시') : zdate($end_date, 'Y.m.d. H시');
		}
		else
		{
			// 시작 시각은 분까지 출력
			$startline = $this_year ? zdate($start_date, 'm.d H시i분'): zdate($start_date, 'Y.m.d H시i분');
			$str = $startline . ' ~ ';
			// 시작과 종료가 같은 시각이라면
			if ( substr($start_date, 0, 12) === substr($end_date, 0, 12) ) $str = $startline;
			// 시까지 같다면
			elseif ( substr($start_date, 0, 10) === substr($end_date, 0, 10) ) $str .= zdate($end_date, 'i분');
			// 일자까지 같다면
			elseif ( substr($start_date, 0, 8) === substr($end_date, 0, 8) ) $str .= zdate($end_date, 'H시i분');
			// 년도만 같다면
			else if ( substr($startline, 0, 4) === substr($end_date, 0, 4) ) $str .= zdate($end_date, 'm.d H시i분');
			// 년도가 다르다면
			else $str .= $this_year ? zdate($end_date, 'm.d H시i분'): zdate($end_date, 'Y.m.d H시i분');
		}
	}
	return $str;
}

시험지 설정 시험기간에서 분단위 입력 문제

시작시간과 종료시간을 입력하려면 달력과 시간 위젯이 뜨는데요.
이 위젯에서는 시간 단위만 입력되고 분 단위를 입력할 수가 없습니다.
이 부분에 대한 개선이 필요해보입니다.

시험지 설정을 변경할 경우 수동으로 된 배점이 초기화 됨

수동으로 배점을 한 이후
시험지 설정을 변경할 경우 배점 설정이 초기화 됨.

스킨에서 create.html 파일에 아래와 같이 exam_total_point 값 추가 필요

input type="hidden" name="exam_total_point" id="exam_total_point" value="{($examitem->get('total_point'))? $examitem->get('total_point') : '0'}" maxlength="3"

시험지 설정 시작시간에서 초단위 문제

시험지 설정 화면(act=dispExamCreate)에서
시작시간의 초단위가 자동입력되는 현상이 있습니다.

해당 설정을 초기화해서 시작시간을 재입력하면 00초 단위로 잘 입력되지만,
설정을 수정하기 위해 들어가면 value값 초단위에 현재시각의 초가 자동 반영됩니다.
시험지 설정을 '등록'라고 나면 start_date 값에 해당 초값이 저장되게 되구요.

입력할 때 아예 초단위를 제거하는 것이 차라리 나을 것 같습니다.

채점 결과 확인할 때 카테고리 번호 제공

현재 시험지나 시험지 리스트 변수에는 카테고리 번호가 제공되고 있습니다만,
채점 결과($resultitem) 및 채점 결과 리스트($result_list) 변수에는 카테고리 번호가 누락되어 있습니다.

확인해보니 각각 getResult와 getResultList 쿼리에서 exam 테이블에서 title과 result_type 칼럼을 가져오고 있는데요.
각각의 쿼리 xml에서 칼럼에
<column name="exam.category_srl" />
를 추가해서 채점 결과 및 리스트 변수에서도 시험 카테고리를 가져오면 좋겠습니다.

그렇게 하면 시험 응시 현황 페이지 및 채점 결과 팝업 창 등에서도 시험의 분류 제목을 출력하는 것이 용이해질 수 있겠습니다.

<채점 결과 화면>
00

<시험 응시 현황 화면>
01

getEditor()를 getModuleEditor()로 교체

현재 시험모듈에서 위지윅 에디터는 시험문제 출제 및 수정 화면에서 로드됩니다.
시험모듈에서 에디터 설정은 스킨 지정 외에는 별다른 옵션이 없는 상태입니다.

물론 모듈 내에서 다양한 에디터 설정 옵션을 두는 것도 좋겠지만, 현실적으로 모듈 내에서 에디터 활용이 잦은 것도 아니어서 그보다는 간소한 방법을 선택하는 것이 더 나을 것 같습니다.

그래서 exam.view.php 파일의 dispExamEditMode 함수에서 에디터 로드를 할 때,
설정을 수동 지정해서 로드하는 getEditor 함수보다는,
아예 에디터 모듈로부터 getModuleEditor 함수를 가져오는 게 더 나아보입니다.

그런 맥락에서 421행부터 에디터를 가져오는 부분을 아래와 같이 하는 것이 어떨까 합니다.

// 지문에서 사용할 에디터 로드
$oEditorModel = getModel('editor');
$editor = $oEditorModel->getModuleEditor('exam', $this->module_srl, $question_srl, 'question_srl', 'q_description_content');
Context::set('editor', $editor);

이렇게 하면 (특히 라이믹스의 모바일 ck에디터의 경우에는) 좀 더 효과적인 툴바를 가져오는 이점도 챙길 수 있을 것으로 기대됩니다.

tpl/result_list.html 오타 수정

채점 결과 링크 주소에 오타가 있어서
채점 결과 팝업창이 지정된 스킨이 아니라 기본 스킨으로만 열리는 문제가 있습니다.

tpl/result_list.html 60행의
$module_info->mid->mid 를 $module_info->mid 으로 바꿔야겠습니다~

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.