#472 세션을 파일기반이 아닌 DB기반으로 사용하도록 변경하고 접속자 출력 위젯 추가

git-svn-id: http://xe-core.googlecode.com/svn/sandbox@4290 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
zero 2008-06-18 06:56:29 +00:00
parent 474ca4df06
commit ea2fede30e
42 changed files with 702 additions and 111 deletions

View file

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<module version="0.1" category="base">
<title xml:lang="ko">Session관리자</title>
<author email_address="zero@zeroboard.com" link="http://www.zeroboard.com" date="2008. 6. 18">
<name xml:lang="ko">zero</name>
<description xml:lang="ko">
접속자의 session을 관리하는 모듈입니다.
기본적인 세션 설정과 사용뿐 아니라 세션 정보를 이용하여 접속자등의 세션 기반의 정보를 제공하는 기능도 있습니다.
</description>
</author>
</module>

View file

@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<module>
<grants />
<permissions />
<actions>
<action name="dispSessionAdminIndex" type="view" standalone="true" admin_index="true" />
<action name="procSessionAdminClear" type="controller" standalone="true" />
</actions>
</module>

View file

@ -0,0 +1,13 @@
<?php
/**
* @file modules/session/lang/ko.lang.php
* @author zero <zero@nzeo.com>
* @brief 한국어 언어팩 (기본적인 내용만 수록)
**/
$lang->session = '세션';
$lang->about_session = "세션 관리를 하는 모듈입니다\n틈틈히 세션 정리를 하시면 사이트 운영시 보다 좋은 효과를 낼 수 있습니다.";
$lang->cmd_clear_session = '세션 정리';
$lang->session_cleared = '쓸모 없는 세션 정보가 정리되었습니다';
?>

View file

@ -0,0 +1,8 @@
<query id="deleteSession" action="delete">
<tables>
<table name="session" />
</tables>
<conditions>
<condition operation="equal" column="session_key" var="session_key" notnull="notnull" />
</conditions>
</query>

View file

@ -0,0 +1,8 @@
<query id="gcSession" action="delete">
<tables>
<table name="session" />
</tables>
<conditions>
<condition operation="less" column="expired" default="curdate()" notnull="notnull" />
</conditions>
</query>

View file

@ -0,0 +1,19 @@
<query id="getLoggedMembers" action="select">
<tables>
<table name="session" />
</tables>
<columns>
<column name="member_srl" />
</columns>
<conditions>
<condition operation="more" column="last_update" var="last_update" notnull="notnull" />
</conditions>
<navigation>
<list_count var="list_count" default="20" />
<page_count var="page_count" default="10" />
<page var="page" default="1" />
</navigation>
<groups>
<group column="member_srl" />
</groups>
</query>

View file

@ -0,0 +1,14 @@
<query id="getLoggedMembers" action="select">
<tables>
<table name="session" />
</tables>
<columns>
<column name="member_srl" />
</columns>
<conditions>
<condition operation="more" column="last_update" var="last_update" notnull="notnull" />
</conditions>
<groups>
<group column="member_srl" />
</groups>
</query>

View file

@ -0,0 +1,11 @@
<query id="getSession" action="select">
<tables>
<table name="session" />
</tables>
<columns>
<column name="*" />
</columns>
<conditions>
<condition operation="equal" column="session_key" var="session_key" notnull="notnull" />
</conditions>
</query>

View file

@ -0,0 +1,13 @@
<query id="insertSession" action="insert">
<tables>
<table name="session" />
</tables>
<columns>
<column name="session_key" var="session_key" notnull="notnull" />
<column name="member_srl" var="member_srl" filter="number" default="0" />
<column name="expired" var="expired" />
<column name="val" var="val" />
<column name="ipaddress" default="ipaddress()" />
<column name="last_update" default="curdate()" />
</columns>
</query>

View file

@ -0,0 +1,15 @@
<query id="updateSession" action="update">
<tables>
<table name="session" />
</tables>
<columns>
<column name="member_srl" var="member_srl" filter="number" default="0" />
<column name="expired" var="expired" />
<column name="val" var="val" notnull="notnull" />
<column name="ipaddress" default="ipaddress()" />
<column name="last_update" default="curdate()" />
</columns>
<conditions>
<condition operation="equal" column="session_key" var="session_key" notnull="notnull" />
</conditions>
</query>

View file

@ -0,0 +1,8 @@
<table name="session">
<column name="session_key" type="varchar" size="255" notnull="notnull" primary_key="primary_key" />
<column name="member_srl" type="number" size="11" notnull="notnull" index="idx_session_member_srl" />
<column name="expired" type="date" index="idx_session_expired" />
<column name="val" type="bigtext" />
<column name="ipaddress" type="varchar" size="128" notnull="notnull" />
<column name="last_update" type="date" index="idx_session_update" />
</table>

View file

@ -0,0 +1,26 @@
<?php
/**
* @class sessionAdminController
* @author zero (zero@nzeo.com)
* @brief session 모듈의 admin controller class
**/
class sessionAdminController extends session {
/**
* @brief 초기화
**/
function init() {
}
/**
* @brief 더비 세션 정리하는 action
**/
function procSessionAdminClear() {
$oSessionController = &getController('session');
$oSessionController->gc(0);
$this->add('result',Context::getLang('session_cleared'));
}
}
?>

View file

@ -0,0 +1,26 @@
<?php
/**
* @class sessionAdminView
* @author zero (zero@nzeo.com)
* @brief session모듈의 admin view class
**/
class sessionAdminView extends session {
/**
* @brief 초기화
**/
function init() {
}
/**
* @brief 설정
**/
function dispSessionAdminIndex() {
// 템플릿 파일 지정
$this->setTemplatePath($this->module_path.'tpl');
$this->setTemplateFile('index');
}
}
?>

View file

@ -0,0 +1,87 @@
<?php
/**
* @class session
* @author zero (zero@nzeo.com)
* @brief session 모듈의 high class
* @version 0.1
*
* session 관리를 하는 class
**/
class session extends ModuleObject {
var $lifetime = 18000;
var $session_started = false;
function session() {
if(Context::isInstalled()) $this->session_started= true;
}
/**
* @brief 설치시 추가 작업이 필요할시 구현
**/
function moduleInstall() {
// action forward에 등록 (관리자 모드에서 사용하기 위함)
$oModuleController = &getController('module');
$oModuleController->insertActionForward('session', 'view', 'dispSessionAdminIndex');
return new Object();
}
/**
* @brief 설치가 이상이 없는지 체크하는 method
**/
function checkUpdate() {
$oDB = &DB::getInstance();
$oModuleModel = &getModel('module');
if(!$oModuleModel->getActionForward('dispSessionAdminIndex')) return true;
if(!$oDB->isTableExists('session')) return true;
return false;
}
/**
* @brief 업데이트 실행
**/
function moduleUpdate() {
$oDB = &DB::getInstance();
$oModuleModel = &getModel('module');
$oModuleController = &getController('module');
if(!$oDB->isTableExists('session')) $oDB->createTableByXmlFile($this->module_path.'schemas/session.xml');
if(!$oModuleModel->getActionForward('dispSessionAdminIndex'))
$oModuleController->insertActionForward('document', 'view', 'dispSessionAdminIndex');
}
/**
* @brief session string decode
**/
function unSerializeSession($val) {
$vars = preg_split('/([a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff^|]*)\|/', $val,-1,PREG_SPLIT_NO_EMPTY | PREG_SPLIT_DELIM_CAPTURE);
for($i=0; $vars[$i]; $i++) $result[$vars[$i++]] = unserialize($vars[$i]);
return $result;
}
/**
* @brief session string encode
**/
function serializeSession($data) {
if(!count($data)) return;
$str = '';
foreach($data as $key => $val) $str .= $key.'|'.serialize($val);
return substr($str, 0, strlen($str)-1).'}';
}
/**
* @brief 캐시 파일 재생성
**/
function recompileCache() {
// 기존 파일 기반의 세션 삭제
FileHandler::removeDir(_XE_PATH_."files/sessions");
}
}
?>

View file

@ -0,0 +1,65 @@
<?php
/**
* @class sessionController
* @author zero (zero@nzeo.com)
* @brief session 모듈의 controller class
**/
class sessionController extends session {
/**
* @brief 초기화
**/
function init() {
}
function open() {
return true;
}
function close() {
return true;
}
function write($session_key, $val) {
if(!$session_key || !$this->session_started) return;
$args->session_key = $session_key;
$output = executeQuery('session.getSession', $args);
$session_info = $output->data;
if($session_info->session_key == $session_key && $session_info->ipaddress != $_SERVER['REMOTE_ADDR']) {
executeQuery('session.deleteSession', $args);
return true;
}
$args->expired = date("YmdHis", time()+$this->lifetime);
$args->val = $val;
if(Context::get('is_logged')) {
$logged_info = Context::get('logged_info');
$args->member_srl = $logged_info->member_srl;
} else {
$args->member_srl = 0;
}
if($session_info->session_key) $output = executeQuery('session.updateSession', $args);
else $output = executeQuery('session.insertSession', $args);
return true;
}
function destroy($session_key) {
if(!$session_key || !$this->session_started) return;
$args->session_key = $session_key;
executeQuery('session.deleteSession', $args);
return true;
}
function gc($maxlifetime) {
if(!$this->session_started) return;
executeQuery('session.gcSession');
return true;
}
}
?>

View file

@ -0,0 +1,63 @@
<?php
/**
* @class sessionModel
* @author zero (zero@nzeo.com)
* @brief session 모듈의 Model class
**/
class sessionModel extends session {
/**
* @brief 초기화
**/
function init() {
}
function getLifeTime() {
return $this->lifetime;
}
function read($session_key) {
if(!$session_key || !$this->session_started) return;
$args->session_key = $session_key;
$output = executeQuery('session.getSession', $args);
// 읽기 오류 발생시 테이블 생성 유무 확인
if(!$output->toBool()) {
$oDB = &DB::getInstance();
if(!$oDB->isTableExists('session')) $oDB->createTableByXmlFile($this->module_path.'schemas/session.xml');
}
return $output->data->val;
}
/**
* @brief 현재 접속중인 사용자의 목록을 구함
* period_time 인자의 값을 n으로 하여 최근 n분 이내에 세션을 갱신한 대상을 추출함
**/
function getLoggedMembers($limit_count = 20, $page = 1, $period_time = 3) {
$args->last_update = date("YmdHis", time() - $period_time*60);
$args->page = $page;
$output = executeQueryArray('session.getLoggedMembers', $args);
if(!$output->toBool() || !$output->data) return $output;
$member_srls = array();
foreach($output->data as $key => $val) {
$member_srls[$key] = $val->member_srl;
$member_keys[$val->member_srl] = $key;
}
$member_args->member_srl = implode(',',$member_srls);
$member_output = executeQueryArray('member.getMembers', $member_args);
if($member_output->data) {
foreach($member_output->data as $key => $val) {
$output->data[$member_keys[$val->member_srl]] = $val;
}
}
return $output;
}
}
?>

View file

@ -0,0 +1,8 @@
<!--%import("js/session.js",optimized=false)-->
<h3>{$lang->session} <span class="gray">{$lang->cmd_management}</span></h3>
<div class="infoText">{nl2br($lang->about_session)}</div>
<form action="./" method="post" onsubmit="return false;">
<span class="button"><input type="button" value="{$lang->cmd_clear_session}" onclick="doClearSession(); return false; "/></span>
</form>

View file

@ -0,0 +1,9 @@
function doClearSession() {
var response_tags = new Array('error','message','result');
var params = new Array();
exec_xml('session','procSessionAdminClear', params, completeClearSession, response_tags);
}
function completeClearSession(ret_obj, response_tags) {
alert(ret_obj['result']);
}