#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

@ -73,12 +73,25 @@
// 기본적인 DB정보 세팅
$this->_loadDBInfo();
// 세션 핸들러 지정
$oSessionModel = &getModel('session');
$oSessionController = &getController('session');
session_set_save_handler(
array(&$oSessionController,"open"),
array(&$oSessionController,"close"),
array(&$oSessionModel,"read"),
array(&$oSessionController,"write"),
array(&$oSessionController,"destroy"),
array(&$oSessionController,"gc")
);
session_start();
// 쿠키로 설정된 언어타입 가져오기
if($_COOKIE['lang_type']) $this->lang_type = $_COOKIE['lang_type'];
else $this->lang_type = $this->db_info->lang_type;
// 등록된 기본 언어파일 찾기
$langs = file('./common/lang/lang.info');
$langs = file(_XE_PATH_.'common/lang/lang.info');
$accept_lang = strtolower($_SERVER['HTTP_ACCEPT_LANGUAGE']);
foreach($langs as $val) {
list($lang_prefix, $lang_text) = explode(',',$val);
@ -99,7 +112,7 @@
// 기본 언어파일 로드
$this->lang = &$GLOBALS['lang'];
$this->_loadLang("./common/lang/");
$this->_loadLang(_XE_PATH_."common/lang/");
// Request Method 설정
$this->_setRequestMethod();
@ -129,7 +142,7 @@
}
// rewrite 모듈사용 상태 체크
if(file_exists('./.htaccess')&&$this->db_info->use_rewrite == 'Y') $this->allow_rewrite = true;
if(file_exists(_XE_PATH_.'.htaccess')&&$this->db_info->use_rewrite == 'Y') $this->allow_rewrite = true;
else $this->allow_rewrite = false;
// 기본 JS/CSS 등록
@ -164,6 +177,9 @@
* @brief DB및 기타 자원들의 close
**/
function close() {
// Session Close
if(function_exists('session_write_close')) session_write_close();
// DB close
$oDB = &DB::getInstance();
if(is_object($oDB)&&method_exists($oDB, 'close')) $oDB->close();
@ -828,7 +844,7 @@
* @brief js file 목록을 return
**/
function _getJsFile() {
require_once("./classes/optimizer/Optimizer.class.php");
require_once(_XE_PATH_."classes/optimizer/Optimizer.class.php");
$oOptimizer = new Optimizer();
return $oOptimizer->getOptimizedFiles($this->_getUniqueFileList($this->js_files), "js");
}
@ -863,7 +879,7 @@
* @brief CSS file 목록 return
**/
function _getCSSFile() {
require_once("./classes/optimizer/Optimizer.class.php");
require_once(_XE_PATH_."classes/optimizer/Optimizer.class.php");
$oOptimizer = new Optimizer();
return $oOptimizer->getOptimizedFiles($this->_getUniqueFileList($this->css_files), "css");
}
@ -932,7 +948,7 @@
* @brief db설정내용이 저장되어 있는 config file의 path를 return
**/
function getConfigFile() {
return "./files/config/db.config.php";
return _XE_PATH_."files/config/db.config.php";
}
/**

View file

@ -15,7 +15,7 @@
class DB {
var $count_cache_path = './files/cache/db';
var $count_cache_path = 'files/cache/db';
var $cond_operation = array( ///< 조건문에서 조건을 등호로 표시하는 변수
'equal' => '=',
@ -43,7 +43,7 @@
var $supported_list = array(); ///< 지원하는 DB의 종류, classes/DB/DB***.class.php 를 이용하여 동적으로 작성됨
var $cache_file = './files/cache/queries/'; ///< query cache파일의 위치
var $cache_file = 'files/cache/queries/'; ///< query cache파일의 위치
/**
* @brief DB를 상속받는 특정 db type의 instance를 생성 return
@ -54,15 +54,23 @@
if(!$GLOBALS['__DB__']) {
$class_name = sprintf("DB%s%s", strtoupper(substr($db_type,0,1)), strtolower(substr($db_type,1)));
$class_file = sprintf("./classes/db/%s.class.php", $class_name);
$class_file = sprintf("%sclasses/db/%s.class.php", _XE_PATH_, $class_name);
if(!file_exists($class_file)) new Object(-1, 'msg_db_not_setted');
require_once($class_file);
$eval_str = sprintf('$GLOBALS[\'__DB__\'] = new %s();', $class_name);
$eval_str = sprintf('$GLOBALS[\'__DB__\'][\''.$db_type.'\'] = new %s();', $class_name);
eval($eval_str);
}
return $GLOBALS['__DB__'];
return $GLOBALS['__DB__'][$db_type];
}
/**
* @brief constructor
**/
function DB() {
$this->count_cache_path = _XE_PATH_.$this->count_cache_path;
$this->cache_file = _XE_PATH_.$this->cache_file;
}
/**
@ -77,7 +85,7 @@
* @brief 지원 가능한 DB 목록을 return
**/
function _getSupportedList() {
$db_classes_path = "./classes/db/";
$db_classes_path = _XE_PATH_."classes/db/";
$filter = "/^DB([^\.]+)\.class\.php/i";
$supported_list = FileHandler::readDir($db_classes_path, $filter, true);
sort($supported_list);
@ -89,7 +97,7 @@
if(version_compare(phpversion(), '5.0') < 0 && preg_match('/pdo/i',$db_type)) continue;
$class_name = sprintf("DB%s%s", strtoupper(substr($db_type,0,1)), strtolower(substr($db_type,1)));
$class_file = sprintf("./classes/db/%s.class.php", $class_name);
$class_file = sprintf(_XE_PATH_."classes/db/%s.class.php", $class_name);
if(!file_exists($class_file)) continue;
unset($oDB);
@ -144,7 +152,7 @@
$str .= sprintf("\t Query Failed : %d\n\t\t\t %s\n", $this->errno, $this->errstr);
if(__DEBUG_DB_OUTPUT__==1) {
$debug_file = "./files/_debug_db_query.php";
$debug_file = _XE_PATH_."files/_debug_db_query.php";
$buff = sprintf("%s\n",print_r($str,true));
if($display_line) $buff = "\n====================================\n".$buff."------------------------------------\n";
@ -161,7 +169,7 @@
// __LOG_SLOW_QUERY__ 가 정해져 있다면 시간 체크후 쿼리 로그 남김
if(__LOG_SLOW_QUERY__>0 && $elapsed_time > __LOG_SLOW_QUERY__) {
$buff = '';
$log_file = './files/_db_slow_query.php';
$log_file = _XE_PATH_.'files/_db_slow_query.php';
if(!file_exists($log_file)) {
$buff = '<?php exit();?>'."\n";
}
@ -218,17 +226,17 @@
}
if(!$target || !$module || !$id) return new Object(-1, 'msg_invalid_queryid');
$xml_file = sprintf('./%s/%s/queries/%s.xml', $target, $module, $id);
$xml_file = sprintf('%s%s/%s/queries/%s.xml', _XE_PATH_, $target, $module, $id);
if(!file_exists($xml_file)) return new Object(-1, 'msg_invalid_queryid');
// 일단 cache 파일을 찾아본다
$cache_file = sprintf('%s%s.cache.php', $this->cache_file, $query_id);
$cache_file = sprintf('%s%s%s.cache.php', _XE_PATH_, $this->cache_file, $query_id);
if(file_exists($cache_file)) $cache_time = filemtime($cache_file);
else $cache_time = -1;
// 캐시 파일이 없거나 시간 비교하여 최근것이 아니면 원본 쿼리 xml파일을 찾아서 파싱을 한다
if($cache_time<filemtime($xml_file) || $cache_time < filemtime('./classes/db/DB.class.php')) {
require_once('./classes/xml/XmlQueryParser.class.php');
if($cache_time<filemtime($xml_file) || $cache_time < filemtime(_XE_PATH_.'classes/db/DB.class.php')) {
require_once(_XE_PATH_.'classes/xml/XmlQueryParser.class.php');
$oParser = new XmlQueryParser();
$oParser->parse($query_id, $xml_file, $cache_file);
}

View file

@ -668,7 +668,7 @@
* 그닥 좋지는 않은 구조이지만 편리하다.. -_-;
**/
function _getNavigationData($table_list, $columns, $condition, $output) {
require_once('./classes/page/PageHandler.class.php');
require_once(_XE_PATH_.'classes/page/PageHandler.class.php');
// 전체 개수를 구함
$count_query = sprintf('select count(*) as "count" from %s %s', implode(',',$table_list), $condition);

View file

@ -814,7 +814,7 @@
* 그닥 좋지는 않은 구조이지만 편리하다.. -_-;
**/
function _getNavigationData($table_list, $columns, $condition, $output) {
require_once('./classes/page/PageHandler.class.php');
require_once(_XE_PATH_.'classes/page/PageHandler.class.php');
// 전체 개수를 구함
$count_query = sprintf('select count(*) as "count" from %s %s;', implode(',',$table_list), $condition);

View file

@ -546,7 +546,7 @@
* 그닥 좋지는 않은 구조이지만 편리하다.. -_-;
**/
function _getNavigationData($table_list, $columns, $condition, $output) {
require_once('./classes/page/PageHandler.class.php');
require_once(_XE_PATH_.'classes/page/PageHandler.class.php');
// 전체 개수를 구함
$count_query = sprintf("select count(*) as count from %s %s", implode(',',$table_list), $condition);

View file

@ -556,7 +556,7 @@
* 그닥 좋지는 않은 구조이지만 편리하다.. -_-;
**/
function _getNavigationData($table_list, $columns, $condition, $output) {
require_once('./classes/page/PageHandler.class.php');
require_once(_XE_PATH_.'classes/page/PageHandler.class.php');
// 전체 개수를 구함
$count_query = sprintf("select count(*) as count from %s %s", implode(',',$table_list), $condition);

View file

@ -545,7 +545,7 @@
* 그닥 좋지는 않은 구조이지만 편리하다.. -_-;
**/
function _getNavigationData($table_list, $columns, $condition, $output) {
require_once('./classes/page/PageHandler.class.php');
require_once(_XE_PATH_.'classes/page/PageHandler.class.php');
// 전체 개수를 구함
$count_query = sprintf("select count(*) as count from %s %s", implode(',',$table_list), $condition);

View file

@ -564,7 +564,7 @@
* 그닥 좋지는 않은 구조이지만 편리하다.. -_-;
**/
function _getNavigationData($table_list, $columns, $condition, $output) {
require_once('./classes/page/PageHandler.class.php');
require_once(_XE_PATH_.'classes/page/PageHandler.class.php');
// 전체 개수를 구함
$count_query = sprintf("select count(*) as count from %s %s", implode(',',$table_list), $condition);

View file

@ -605,7 +605,7 @@
* 그닥 좋지는 않은 구조이지만 편리하다.. -_-;
**/
function _getNavigationData($table_list, $columns, $condition, $output) {
require_once('./classes/page/PageHandler.class.php');
require_once(_XE_PATH_.'classes/page/PageHandler.class.php');
// 전체 개수를 구함
$count_query = sprintf("select count(*) as count from %s %s", implode(',',$table_list), $condition);

View file

@ -88,8 +88,10 @@
* 주어진 경로를 단계별로 접근하여 recursive하게 디렉토리 생성
**/
function makeDir($path_string) {
$path_string = str_replace(_XE_PATH_,'',$path_string);
$path_list = explode('/', $path_string);
$path = _XE_PATH_;
for($i=0;$i<count($path_list);$i++) {
if(!$path_list[$i]) continue;
$path .= $path_list[$i].'/';

View file

@ -63,7 +63,7 @@
// 애드온 실행 (모듈 실행 전)
$called_position = 'before_module_init';
@include("./files/cache/activated_addons.cache.php");
@include(_XE_PATH_."files/cache/activated_addons.cache.php");
}
/**
@ -251,10 +251,7 @@
* @brief module의 위치를 찾아서 return
**/
function getModulePath($module) {
$class_path = sprintf('./modules/%s/', $module);
if(is_dir($class_path)) return $class_path;
return "";
return sprintf('./modules/%s/', $module);
}
/**
@ -262,7 +259,7 @@
**/
function &getModuleInstance($module, $type = 'view', $kind = '') {
$class_path = ModuleHandler::getModulePath($module);
if(!$class_path) return NULL;
if(!is_dir(_XE_PATH_.$class_path)) return NULL;
if(__DEBUG__==3) $start_time = getMicroTime();
@ -277,7 +274,7 @@
// 상위 클래스명 구함
if(!class_exists($module)) {
$high_class_file = sprintf('%s%s.class.php', $class_path, $module);
$high_class_file = sprintf('%s%s%s.class.php', _XE_PATH_,$class_path, $module);
if(!file_exists($high_class_file)) return NULL;
require_once($high_class_file);
}
@ -287,33 +284,33 @@
case 'controller' :
if($kind == 'admin') {
$instance_name = sprintf("%sAdmin%s",$module,"Controller");
$class_file = sprintf('%s%s.admin.%s.php', $class_path, $module, $type);
$class_file = sprintf('%s%s%s.admin.%s.php', _XE_PATH_, $class_path, $module, $type);
} else {
$instance_name = sprintf("%s%s",$module,"Controller");
$class_file = sprintf('%s%s.%s.php', $class_path, $module, $type);
$class_file = sprintf('%s%s%s.%s.php', _XE_PATH_, $class_path, $module, $type);
}
break;
case 'model' :
if($kind == 'admin') {
$instance_name = sprintf("%sAdmin%s",$module,"Model");
$class_file = sprintf('%s%s.admin.%s.php', $class_path, $module, $type);
$class_file = sprintf('%s%s%s.admin.%s.php', _XE_PATH_, $class_path, $module, $type);
} else {
$instance_name = sprintf("%s%s",$module,"Model");
$class_file = sprintf('%s%s.%s.php', $class_path, $module, $type);
$class_file = sprintf('%s%s%s.%s.php', _XE_PATH_, $class_path, $module, $type);
}
break;
case 'class' :
$instance_name = $module;
$class_file = sprintf('%s%s.class.php', $class_path, $module);
$class_file = sprintf('%s%s%s.class.php', _XE_PATH_, $class_path, $module);
break;
default :
$type = 'view';
if($kind == 'admin') {
$instance_name = sprintf("%sAdmin%s",$module,"View");
$class_file = sprintf('%s%s.admin.view.php', $class_path, $module, $type);
$class_file = sprintf('%s%s%s.admin.view.php', _XE_PATH_, $class_path, $module, $type);
} else {
$instance_name = sprintf("%s%s",$module,"View");
$class_file = sprintf('%s%s.view.php', $class_path, $module, $type);
$class_file = sprintf('%s%s%s.view.php', _XE_PATH_, $class_path, $module, $type);
}
break;
}
@ -361,7 +358,7 @@
$oModuleModel = &getModel('module');
$cache_dir = sprintf("./files/cache/triggers/");
$cache_dir = sprintf("%sfiles/cache/triggers/",_XE_PATH_);
if(!is_dir($cache_dir)) FileHandler::makeDir($cache_dir);
$cache_file = sprintf("%s%s.%s", $cache_dir, $trigger_name, $called_position);

View file

@ -228,7 +228,7 @@
* @brief template 경로 지정
**/
function setTemplatePath($path) {
if(substr($path,0,2)!='./') $path = './'.$path;
if(substr($path,0,1)!='/' && substr($path,0,2)!='./') $path = './'.$path;
if(substr($path,-1)!='/') $path .= '/';
$this->template_path = $path;
}
@ -274,8 +274,8 @@
* @brief layout 경로 지정
**/
function setLayoutPath($path) {
if(substr($path,0,1)!='/' && substr($path,0,2)!='./') $path = './'.$path;
if(substr($path,-1)!='/') $path .= '/';
if(substr($path,0,2)!='./') $path = './'.$path;
$this->layout_path = $path;
}
@ -297,7 +297,7 @@
// addon 실행(called_position 를 before_module_proc로 하여 호출)
$called_position = 'before_module_proc';
@include("./files/cache/activated_addons.cache.php");
@include(_XE_PATH_."files/cache/activated_addons.cache.php");
// 지금까지 이상이 없었다면 action 실행
if(!$this->stop_proc) {
@ -347,7 +347,7 @@
// addon 실행(called_position 를 after_module_proc로 하여 호출)
$called_position = 'after_module_proc';
@include("./files/cache/activated_addons.cache.php");
@include(_XE_PATH_."files/cache/activated_addons.cache.php");
if(is_a($output, 'Object') || is_subclass_of($output, 'Object')) {
$this->setError($output->getError());

View file

@ -49,12 +49,12 @@
$output->tables[$alias] = $table_name;
// 테이블을 찾아서 컬럼의 속성을 구함
$table_file = sprintf('./%s/%s/schemas/%s.xml', 'modules', $module, $table_name);
$table_file = sprintf('%s%s/%s/schemas/%s.xml', _XE_PATH_, 'modules', $module, $table_name);
if(!file_exists($table_file)) {
$searched_list = FileHandler::readDir('./modules');
$searched_list = FileHandler::readDir(_XE_PATH_.'modules');
$searched_count = count($searched_list);
for($i=0;$i<$searched_count;$i++) {
$table_file = sprintf('./%s/%s/schemas/%s.xml', 'modules', $searched_list[$i], $table_name);
$table_file = sprintf('%s%s/%s/schemas/%s.xml', _XE_PATH_, 'modules', $searched_list[$i], $table_name);
if(file_exists($table_file)) break;
}
}

View file

@ -126,6 +126,9 @@ function drawTreeMenu(oXml, callback_func, resopnse_tags, null_func, param) {
if(manual_select_node_srl) manualSelectNode(menu_id, manual_select_node_srl);
}
var waiting_obj = xGetElementById("waitingforserverresponse");
if(waiting_obj) waiting_obj.style.visibility = "hidden";
return null;
}

View file

@ -55,10 +55,15 @@
**/
define('__OB_GZHANDLER_ENABLE__', 1);
/**
* @brief zbXE가 설치된 장소의 base path를 구함
**/
define('_XE_PATH_', str_replace('config/config.inc.php','',__FILE__));
/**
* @brief 간단하게 사용하기 위한 함수 정의한 파일 require
**/
require_once('./config/func.inc.php');
require_once(_XE_PATH_.'config/func.inc.php');
if(__DEBUG__) define('__StartTime__', getMicroTime());
@ -69,33 +74,18 @@
* php5 기반으로 바꾸게 되면 _autoload를 이용할 있기에 제거 대상
**/
if(__DEBUG__) define('__ClassLoadStartTime__', getMicroTime());
require_once('./classes/object/Object.class.php');
require_once('./classes/handler/Handler.class.php');
require_once('./classes/xml/XmlParser.class.php');
require_once('./classes/context/Context.class.php');
require_once('./classes/db/DB.class.php');
require_once('./classes/file/FileHandler.class.php');
require_once('./classes/widget/WidgetHandler.class.php');
require_once('./classes/editor/EditorHandler.class.php');
require_once('./classes/module/ModuleObject.class.php');
require_once('./classes/module/ModuleHandler.class.php');
require_once('./classes/display/DisplayHandler.class.php');
require_once('./classes/template/TemplateHandler.class.php');
require_once('./classes/mail/Mail.class.php');
require_once(_XE_PATH_.'classes/object/Object.class.php');
require_once(_XE_PATH_.'classes/handler/Handler.class.php');
require_once(_XE_PATH_.'classes/xml/XmlParser.class.php');
require_once(_XE_PATH_.'classes/context/Context.class.php');
require_once(_XE_PATH_.'classes/db/DB.class.php');
require_once(_XE_PATH_.'classes/file/FileHandler.class.php');
require_once(_XE_PATH_.'classes/widget/WidgetHandler.class.php');
require_once(_XE_PATH_.'classes/editor/EditorHandler.class.php');
require_once(_XE_PATH_.'classes/module/ModuleObject.class.php');
require_once(_XE_PATH_.'classes/module/ModuleHandler.class.php');
require_once(_XE_PATH_.'classes/display/DisplayHandler.class.php');
require_once(_XE_PATH_.'classes/template/TemplateHandler.class.php');
require_once(_XE_PATH_.'classes/mail/Mail.class.php');
if(__DEBUG__) $GLOBALS['__elapsed_class_load__'] = getMicroTime() - __ClassLoadStartTime__;
/**
* @brief 세션 설정
* 세션의 파기 시간을 5시간으로 하고 세션 저장 경로를 files/session 으로 변경
**/
if(!ini_get('session.auto_start')) {
session_cache_limiter('no-cache, must-revalidate');
ini_set('session.gc_maxlifetime', '18000');
if(!is_dir('./files/sessions')) {
FileHandler::makeDir('./files/sessions');
@chmod('./files/sessions', 0777);
}
if(is_dir('./files/sessions')) session_save_path(realpath('.').'/files/sessions/');
session_start();
}
?>

View file

@ -313,7 +313,7 @@
* tail -f ./files/_debug_message.php 하여 계속 살펴 있다
**/
function debugPrint($buff = null, $display_line = true) {
$debug_file = "./files/_debug_message.php";
$debug_file = _XE_PATH_."files/_debug_message.php";
$buff = sprintf("%s\n",print_r($buff,true));
if($display_line) $buff = "\n====================================\n".$buff."------------------------------------\n";

View file

@ -793,23 +793,52 @@
$tree[$parent_srl][$category_srl] = $node;
}
// 세션 디렉토리 변경 구문
$php_script = "";
if(!ini_get('session.auto_start')) {
if(!is_dir("./files/sessions")) {
FileHandler::makeDir("./files/sessions");
@chmod("./files/sessions", 0777);
}
// 캐시 파일의 권한과 그룹 설정을 위한 공통 헤더
$header_script =
'$lang_type = Context::getLangType(); '.
'$is_logged = Context::get(\'is_logged\'); '.
'$logged_info = Context::get(\'logged_info\'); '.
'if($is_logged && $logged_info->is_admin=="Y") { '.
'$is_admin = true; '.
'$group_srls = array_keys($logged_info->group_list); '.
'} else { '.
'$is_admin = false; '.
'$group_srsl = array(); '.
'} ';
$php_script = 'session_cache_limiter("no-cache, must-revalidate"); ini_set("session.gc_maxlifetime", "18000"); if(is_dir("../../sessions")) session_save_path("../../sessions/"); session_start();';
}
// xml 캐시 파일 생성
$xml_buff = sprintf('<?php %s header("Content-Type: text/xml; charset=UTF-8"); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); @session_start(); ?><root>%s</root>', $php_script, $this->getXmlTree($tree[0], $tree));
// xml 캐시 파일 생성 (xml캐시는 따로 동작하기에 session 지정을 해주어야 함)
$xml_buff = sprintf(
'<?php '.
'define(\'__ZBXE__\', true); '.
'require_once(\'../../../config/config.inc.php\'); '.
'$oContext = &Context::getInstance(); '.
'$oContext->init(); '.
'header("Content-Type: text/xml; charset=UTF-8"); '.
'header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); '.
'header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); '.
'header("Cache-Control: no-store, no-cache, must-revalidate"); '.
'header("Cache-Control: post-check=0, pre-check=0", false); '.
'header("Pragma: no-cache"); '.
'%s'.
'?>'.
'<root>%s</root>',
$header_script,
$this->getXmlTree($tree[0], $tree)
);
// php 캐시 파일 생성
$php_output = $this->getPhpCacheCode($tree[0], $tree, 0);
$php_buff = sprintf('<?php if(!defined("__ZBXE__")) exit(); %s; $menu->list = array(%s); ?>', $php_output['category_title_str'], $php_output['buff']);
$php_buff = sprintf(
'<?php '.
'if(!defined("__ZBXE__")) exit(); '.
'%s; '.
'%s; '.
'$menu->list = array(%s); '.
'?>',
$header_script,
$php_output['category_title_str'],
$php_output['buff']
);
// 파일 저장
FileHandler::writeFile($xml_file, $xml_buff);
@ -839,7 +868,7 @@
$module_srl = $node->module_srl;
// node->group_srls값이 있으면
if($group_srls) $group_check_code = sprintf('($_SESSION["is_admin"]==true||(is_array($_SESSION["group_srls"])&&count(array_intersect($_SESSION["group_srls"], array(%s)))))',$group_srls);
if($group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$group_srls);
else $group_check_code = "true";
$attribute = sprintf(
@ -886,7 +915,7 @@
$output['category_srl_list'] = array_merge($output['category_srl_list'], $child_output['category_srl_list']);
// node->group_srls값이 있으면
if($node->group_srls) $group_check_code = sprintf('($_SESSION["is_admin"]==true||(is_array($_SESSION["group_srls"])&&count(array_intersect($_SESSION["group_srls"], array(%s)))))',$node->group_srls);
if($node->group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$node->group_srls);
else $group_check_code = "true";
// 변수 정리

View file

@ -349,23 +349,52 @@
$tree[$parent_srl][$menu_item_srl] = $node;
}
// 세션 디렉토리 변경 구문
$php_script = "";
if(!ini_get('session.auto_start')) {
if(!is_dir("./files/sessions")) {
FileHandler::makeDir("./files/sessions");
@chmod("./files/sessions", 0777);
}
// 캐시 파일의 권한과 그룹 설정을 위한 공통 헤더
$header_script =
'$lang_type = Context::getLangType(); '.
'$is_logged = Context::get(\'is_logged\'); '.
'$logged_info = Context::get(\'logged_info\'); '.
'if($is_logged && $logged_info->is_admin=="Y") { '.
'$is_admin = true; '.
'$group_srls = array_keys($logged_info->group_list); '.
'} else { '.
'$is_admin = false; '.
'$group_srsl = array(); '.
'} ';
$php_script = 'session_cache_limiter("no-cache, must-revalidate"); ini_set("session.gc_maxlifetime", "18000"); if(is_dir("../../sessions")) session_save_path("../../sessions/"); session_start();';
}
// xml 캐시 파일 생성
$xml_buff = sprintf('<?php %s header("Content-Type: text/xml; charset=UTF-8"); header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); header("Cache-Control: no-store, no-cache, must-revalidate"); header("Cache-Control: post-check=0, pre-check=0", false); header("Pragma: no-cache"); @session_start(); if($_SESSION["logged_info"]&&$_SESSION["logged_info"]->is_admin=="Y") $_is_admin = true; ?><root>%s</root>', $php_script, $this->getXmlTree($tree[0], $tree));
// xml 캐시 파일 생성 (xml캐시는 따로 동작하기에 session 지정을 해주어야 함)
$xml_buff = sprintf(
'<?php '.
'define(\'__ZBXE__\', true); '.
'require_once(\'../../../config/config.inc.php\'); '.
'$oContext = &Context::getInstance(); '.
'$oContext->init(); '.
'header("Content-Type: text/xml; charset=UTF-8"); '.
'header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); '.
'header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT"); '.
'header("Cache-Control: no-store, no-cache, must-revalidate"); '.
'header("Cache-Control: post-check=0, pre-check=0", false); '.
'header("Pragma: no-cache"); '.
'%s'.
'?>'.
'<root>%s</root>',
$header_script,
$this->getXmlTree($tree[0], $tree)
);
// php 캐시 파일 생성
$php_output = $this->getPhpCacheCode($tree[0], $tree);
$php_buff = sprintf('<?php if(!defined("__ZBXE__")) exit(); if($_SESSION["logged_info"]&&$_SESSION["logged_info"]->is_admin=="Y") $_is_admin = true; $lang_type = Context::getLangType(); %s; $menu->list = array(%s); ?>', $php_output['name'], $php_output['buff']);
$php_buff = sprintf(
'<?php '.
'if(!defined("__ZBXE__")) exit(); '.
'%s; '.
'%s; '.
'$menu->list = array(%s); '.
'?>',
$header_script,
$php_output['name'],
$php_output['buff']
);
// 파일 저장
FileHandler::writeFile($xml_file, $xml_buff);
@ -394,7 +423,7 @@
foreach($names as $key => $val) {
$name_arr_str .= sprintf('"%s"=>"%s",',$key, htmlspecialchars($val));
}
$name_str = sprintf('$_names = array(%s); print $_names[$_SESSION["lang_type"]];', $name_arr_str);
$name_str = sprintf('$_names = array(%s); print $_names[$lang_type];', $name_arr_str);
$url = str_replace(array('&','"','<','>'),array('&amp;','&quot;','&lt;','&gt;'),$node->url);
if(preg_match('/^([0-9a-zA-Z\_\-]+)$/', $node->url)) {
@ -422,13 +451,13 @@
else $classname = '';
if($hover_btn) $hover_str = sprintf('onmouseover=&quot;this.src=\'%s\'&quot;', $hover_btn); else $hover_str = '';
if($active_btn) $active_str = sprintf('onmousedown=&quot;this.src=\'%s\'&quot;', $active_btn); else $active_str = '';
$link = sprintf('&lt;img src=&quot;%s&quot; onmouseout=&quot;this.src=\'%s\'&quot; alt=&quot;<?php print htmlspecialchars($_names[$_SESSION["lang_type"]]) ?>&quot; %s %s %s /&gt;', $normal_btn, $normal_btn, $hover_str, $active_str, $classname);
$link = sprintf('&lt;img src=&quot;%s&quot; onmouseout=&quot;this.src=\'%s\'&quot; alt=&quot;<?php print htmlspecialchars($_names[$lang_type]) ?>&quot; %s %s %s /&gt;', $normal_btn, $normal_btn, $hover_str, $active_str, $classname);
} else {
$link = '<?php print $_names[$_SESSION["lang_type"]]; ?>';
$link = '<?php print $_names[$lang_type]; ?>';
}
// node->group_srls값이 있으면
if($group_srls) $group_check_code = sprintf('($_is_admin==true||(is_array($_SESSION["group_srls"])&&count(array_intersect($_SESSION["group_srls"], array(%s)))))',$group_srls);
if($group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$group_srls);
else $group_check_code = "true";
$attribute = sprintf(
'node_srl="%s" parent_srl="%s" text="<?php if(%s) { %s }?>" url="<?php print(%s?"%s":"")?>" href="<?php print(%s?"%s":"")?>" open_window="%s" expand="%s" normal_btn="%s" hover_btn="%s" active_btn="%s" link="<?php if(%s) {?>%s<?php }?>"',
@ -484,7 +513,7 @@
$output['url_list'] = array_merge($output['url_list'], $child_output['url_list']);
// node->group_srls값이 있으면
if($node->group_srls) $group_check_code = sprintf('($_is_admin==true||(is_array($_SESSION["group_srls"])&&count(array_intersect($_SESSION["group_srls"], array(%s)))))',$node->group_srls);
if($node->group_srls) $group_check_code = sprintf('($is_admin==true||(is_array($group_srls)&&count(array_intersect($group_srls, array(%s)))))',$node->group_srls);
else $group_check_code = "true";
// 변수 정리

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']);
}

View file

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<widget version="0.1">
<title xml:lang="ko">로그인 사용자 출력 위젯</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">
로그인 사용자를 출력하는 위젯입니다.
</description>
</author>
<extra_vars>
<var id="list_count">
<name xml:lang="ko">목록수</name>
<type>text</type>
<description xml:lang="ko">출력될 목록의 수를 정하실 수 있습니다. (기본 5개)</description>
</var>
</extra_vars>
</widget>

View file

@ -0,0 +1,42 @@
<?php
/**
* @class logged_members
* @author zero (zero@nzeo.com)
* @brief 로그인 사용자의 목록을 출력합니다.
* @version 0.1
**/
class logged_members extends WidgetHandler {
/**
* @brief 위젯의 실행 부분
*
* ./widgets/위젯/conf/info.xml 선언한 extra_vars를 args로 받는다
* 결과를 만든후 print가 아니라 return 해주어야 한다
**/
function proc($args) {
// 위젯 자체적으로 설정한 변수들을 체크
$list_count = (int)$args->list_count;
if(!$list_count) $list_count = 5;
// session model 객체 생성
$oSessionModel = &getModel('session');
$output = $oSessionModel->getLoggedMembers($list_count);
$widget_info->member_list = $output->data;
Context::set('widget_info', $widget_info);
// 템플릿의 스킨 경로를 지정 (skin, colorset에 따른 값을 설정)
$tpl_path = sprintf('%sskins/%s', $this->widget_path, $args->skin);
Context::set('colorset', $args->colorset);
// 템플릿 파일을 지정
$tpl_file = 'list';
// 템플릿 컴파일
$oTemplate = &TemplateHandler::getInstance();
$output = $oTemplate->compile($tpl_path, $tpl_file);
return $output;
}
}
?>

View file

@ -0,0 +1,4 @@
.mg { padding-bottom:15px; overflow:hidden; position:relative;}
.mg h2 { font-size:1em; display:block; height:21px; padding:9px 0 0 9px; margin-bottom:4px; color:#000000; background:url(../images/normal/lineNotice.gif) no-repeat left bottom;}
.mg ul { margin:0; padding:0; overflow:hidden; width:100%;}
.mg ul li { white-space:nowrap; padding:3px 0 3px 10px; overflow:hidden; border-bottom:1px dashed #EEEEEE; color:#54564b;}

Binary file not shown.

After

Width:  |  Height:  |  Size: 139 B

View file

@ -0,0 +1,16 @@
<!-- 설정된 컬러셋의 종류에 따라서 css파일을 import 합니다 -->
<!--@if($colorset=="normal"||!$colorset)-->
<!--%import("css/normal.css")-->
<!--@end-->
<div class="mg">
<ul>
<!--@foreach($widget_info->member_list as $key => $val)-->
<li>
<div class="nick_name member_{$val->member_srl}">{htmlspecialchars($val->nick_name)}</div>
</li>
<!--@end-->
</ul>
</div>

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<skin>
<title xml:lang="ko">그룹회원 출력 위젯 기본 스킨</title>
<title xml:lang="jp">グループ会員表示ウィジェットのデフォルトスキン</title>
<title xml:lang="en">Basic Skin of Group Member Display Widget</title>
<title xml:lang="zh-CN">会员列表默认皮肤</title>
<maker email_address="zero@zeroboard.com" link="http://www.zeroboard.com" date="2007. 7. 30">
<name xml:lang="ko">제로</name>
<name xml:lang="jp">Zero</name>
<name xml:lang="en">zero</name>
<name xml:lang="zh-CN">Zero</name>
<description xml:lang="ko">그룹회원 출력 위젯의 기본 스킨</description>
<description xml:lang="jp">グループ会員表示ウィジェットのデフォルトスキン</description>
<description xml:lang="en">Basic skin of group member display widget</description>
<description xml:lang="zh-CN">显示特定用户组会员列表的默认皮肤。</description>
</maker>
<colorset>
<color name="normal">
<title xml:lang="ko">기본 컬러</title>
<title xml:lang="jp">デフォルトカラー</title>
<title xml:lang="en">Default Color</title>
<title xml:lang="zh-CN">默认颜色</title>
</color>
</colorset>
</skin>