git-svn-id: http://xe-core.googlecode.com/svn/trunk@2 201d5d3c-b55e-5fd7-737f-ddc643e51545

This commit is contained in:
zero 2007-02-06 15:11:13 +00:00
parent 2569c554ce
commit c040d4d713
317 changed files with 14496 additions and 0 deletions

View file

@ -0,0 +1,16 @@
<?php
/**
* @file : addons/spam_filter/spam_filter.addon.php
* @author : zero <zero@nzeo.com>
* @desc : 스팸필터링 애드온
**/
class spam_filter {
function proc(&$oModule, $oModuleInfo) {
$oModule->setError(-1);
$oModule->setMessage('error');
}
}
?>

62
admin.php Normal file
View file

@ -0,0 +1,62 @@
<?php
/**
* @file : admin.php
* @author : zero <zero@nzeo.com>
* @desc : 관리자 페이지
* admin은 ModuleHandler를 이용하지 않는다.
**/
// 필요한 설정 파일들을 include
require_once("./config/config.inc.php");
// Request Method와 설정값들을 세팅
$oContext = &Context::getInstance();
$oContext->init();
// 설치가 안되어 있다면 index.php로 이동
if(!Context::isInstalled()) {
header("location:./index.php");
exit();
}
// sid 검사
$sid = Context::get('sid');
if($sid) {
$oModule = module_manager::getAdminModuleObject($sid);
if(!$oModule) {
$sid = null;
Context::set('sid',$sid);
unset($oModule);
}
}
// 관리자(admin) 모듈 객체 생성
$oAdmin = getModule('admin');
$oAdmin->moduleInit(null);
// act검사
$act = Context::get('act');
if(!$sid&&!$oAdmin->isExistsAct($act)) $act = 'dispAdminIndex';
// 관리자 모듈의 실행 결과가 있으면 해당 실행결과를 출력
if($oAdmin->proc($act)) {
$oModule = &$oAdmin;
// 관리자 모듈의 실행 결과가 없으면 호출된 다른 모듈의 관리자를 확인
} else {
$oModule = module_manager::getAdminModuleObject($sid);
if($oModule) {
$oModule->moduleInit(null);
$oModule->proc();
// 관리자용 레이아웃으로 변경
$oModule->setLayoutPath($oAdmin->getLayoutPath());
$oModule->setLayoutTpl($oAdmin->getLayoutTpl());
}
}
// DisplayHandler로 컨텐츠 출력
$oDisplayHandler = new DisplayHandler();
$oDisplayHandler->printContent($oModule);
?>

View file

@ -0,0 +1,51 @@
<?php
/**
* @file : classes/addon/AddOnHandler.class.php
* @author : zero <zero@nzeo.com>
* @desc : addon 실행
**/
class AddOnHandler {
var $addon_name;
function callAddOns(&$oModule, $oModuleInfo, $status) {
if(!$oModuleInfo->isAddOnExists($status, ContextHandler::get('act'))) return;
$addon_list = $oModuleInfo->getAddOnList($status, ContextHandler::get('act'));
$addon_cnt = count($addon_list);
if(!$addon_cnt) return;
for($i=0; $i<$addon_cnt; $i++) {
$addon_name = $addon_list[$i];
$oAddOn = new AddOnHandler($addon_name);
$oAddOn->proc($oModule, $oModuleInfo);
}
}
function AddOnHandler($addon_name) {
$this->addon_name = $addon_name;
}
function proc(&$oModule, $oModuleInfo) {
// 해당 모듈을 읽어서 객체를 만듬
$addon_file = sprintf('./addons/%s/%s.addon.php', $this->addon_name, $this->addon_name);
// 모듈 파일이 없으면 에러
if(!file_exists($addon_file)) return;
// 모듈 파일을 include
require_once($addon_file);
// 선택된 모듈의 instance는 eval string으로 처리
$eval_str = sprintf('$oAddOn = new %s();', $this->addon_name);
eval($eval_str);
// 애드온 실행
$oAddOn->proc($oModule, $oModuleInfo);
}
}
?>

View file

@ -0,0 +1,547 @@
<?php
/**
* @file : clases/context/Context.clas.php
* @author : zero <zero@nzeo.com>
* @desc : Request Argument/Module Config/ Layout-AddOn-Plugin과
* 결과물까지 모두 처리
**/
class Context {
// GET/POST/XMLRPC 중 어떤 방식으로 요청이 왔는지에 대한 값이 세팅
var $request_method = 'GET';
// request parameter 를 정리하여 담을 변수
var $context = NULL;
// DB 정보
var $db_info = NULL;
// js file
var $js_files = array();
// css file
var $css_files = array();
// html header 정보
var $html_header = NULL;
// 언어정보
var $lang_type = 'ko';
var $lang = NULL;
var $loaded_lang_files = array();
// 현 사이트의 title
var $site_title = '';
// 현재 요청 들어온 $_GET을 별도로 정리/보관 ( set method에 의해 값 변경 적용)
var $get_vars = NULL;
// 업로드 유무 체크
var $is_uploaded = false;
/**
* Context 객체 생성 초기화
**/
// public object getInstance()/*{{{*/
// Context는 어디서든 객체 선언없이 사용하기 위해서 static 하게 사용
function &getInstance() {
if(!$GLOBALS['__ContextInstance__']) $GLOBALS['__ContextInstance__'] = new Context();
return $GLOBALS['__ContextInstance__'];
}/*}}}*/
// public void init()/*{{{*/
// DB정보, Request Argument등을 세팅
function init() {
// context 변수를 $GLOBALS의 변수로 지정
$this->context = &$GLOBALS['__Context__'];
$this->context->lang = &$GLOBALS['lang'];
// 인증관련 데이터를 Context에 설정
$oMember = getModule('member');
if($oMember->isLogged()) {
$this->_set('is_logged', true);
$this->_set('logged_info', $_SESSION['logged_info']);
}
// 기본적인 DB정보 세팅
$this->_loadDBInfo();
// 기본 언어파일 로드
$this->lang = &$GLOBALS['lang'];
$this->_loadLang("./common/lang/");
// Request Method 설정
$this->_setRequestMethod();
// Request Argument 설정
$this->_setXmlRpcArgument();
$this->_setRequestArgument();
$this->_setUploadedArgument();
}/*}}}*/
/**
* DB 정보를 설정하고 DB Type과 DB 정보를 return
**/
// private void _loadDBInfo()/*{{{*/
// 설정파일을 통해 DB정보를 로드
function _loadDBInfo() {
if(!$this->isInstalled()) return;
// db 정보 설정
$db_config_file = $this->getConfigFile();
if(file_exists($db_config_file)) {
include $db_config_file;
}
$this->_setDBInfo($db_info);
}/*}}}*/
// public string getDBType()/*{{{*/
// DB의 db_type을 return
function getDBType() {
$oContext = &Context::getInstance();
return $oContext->_getDBType();
}/*}}}*/
// private string _getDBType()/*{{{*/
function _getDBType() {
return $this->db_info->db_type;
}/*}}}*/
// public object setDBInfo($db_info) /*{{{*/
// DB 정보가 담긴 object를 return
function setDBInfo($db_info) {
$oContext = &Context::getInstance();
$oContext->_setDBInfo($db_info);
}/*}}}*/
// private string _setDBInfo($db_info)/*{{{*/
function _setDBInfo($db_info) {
$this->db_info = $db_info;
}/*}}}*/
// public object getDBInfo() /*{{{*/
// DB 정보가 담긴 object를 return
function getDBInfo() {
$oContext = &Context::getInstance();
return $oContext->_getDBInfo();
}/*}}}*/
// private string _getDBInfo()/*{{{*/
function _getDBInfo() {
return $this->db_info;
}/*}}}*/
/**
* 사이트 title
**/
// public void setBrowserTitle($site_title)/*{{{*/
function setBrowserTitle($site_title) {
$oContext = &Context::getInstance();
$oContext->_setBrowserTitle($site_title);
}/*}}}*/
// private void _setBrowserTitle($site_title)/*{{{*/
function _setBrowserTitle($site_title) {
$this->site_title = $site_title;
}/*}}}*/
// public string getBrowserTitle()/*{{{*/
function getBrowserTitle() {
$oContext = &Context::getInstance();
return $oContext->_getBrowserTitle();
}/*}}}*/
// private string _getBrowserTitle() /*{{{*/
function _getBrowserTitle() {
return $this->site_title;
}/*}}}*/
/**
* 언어관련
**/
// public void loadLang($path)/*{{{*/
// 지정된 언어파일 로드
function loadLang($path) {
$oContext = &Context::getInstance();
$oContext->_loadLang($path);
}/*}}}*/
// private void _loadLang($path)/*{{{*/
// 지정된 언어파일 로드
function _loadLang($path) {
global $lang;
if(substr($path,-1)!='/') $path .= '/';
$filename = sprintf('%s%s.lang.php', $path, $this->lang_type);
if(!file_exists($filename)) $filename = sprintf('%slang/%s.lang.php', $path, $this->lang_type);
if(!file_exists($filename)) return;
if(in_array($filename, $this->loaded_lang_files)) return;
$this->loaded_lang_files[] = $filename;
include ($filename);
}/*}}}*/
// public void setLangType($lang_type = 'ko')/*{{{*/
function setLangType($lang_type = 'ko') {
$oContext = &Context::getInstance();
$oContext->_setLangType($lang);
}/*}}}*/
// private void _setLangType($lang_type = 'ko')/*{{{*/
function _setLangType($lang_type = 'ko') {
$this->lang_type = $lang_type;
}/*}}}*/
// public string getLangType()/*{{{*/
function getLangType() {
$oContext = &Context::getInstance();
return $oContext->_getLangType();
}/*}}}*/
// private string _getLangType()/*{{{*/
function _getLangType() {
return $this->lang_type;
}/*}}}*/
// public string getLang($code)/*{{{*/
function getLang($code) {
if($GLOBALS['lang']->{$code}) return $GLOBALS['lang']->{$code};
return $code;
}/*}}}*/
// public string setLang($code, $val)/*{{{*/
function setLang($code, $val) {
$GLOBALS['lang']->{$code} = $val;
}/*}}}*/
// public obj convertEncoding($obj)
// obj내의 문자들을 utf8로 변경
function convertEncoding($source_obj) {/*{{{*/
$charset_list = array(
'UTF-8', 'EUC-KR', 'CP949', 'ISO-8859-1', 'EUC-JP', 'SHIFT_JIS', 'CP932',
'EUC-CN', 'HZ', 'GBK', 'GB18030', 'EUC-TW', 'BIG5', 'CP950', 'BIG5-HKSCS',
'ISO-2022-CN', 'ISO-2022-CN-EXT', 'ISO-2022-JP', 'ISO-2022-JP-2', 'ISO-2022-JP-1',
'ISO-8859-6', 'ISO-8859-8', 'JOHAB', 'ISO-2022-KR', 'CP1255', 'CP1256', 'CP862',
'ASCII', 'ISO-8859-1', 'ISO-8850-2', 'ISO-8850-3', 'ISO-8850-4', 'ISO-8850-5',
'ISO-8850-7', 'ISO-8850-9', 'ISO-8850-10', 'ISO-8850-13', 'ISO-8850-14',
'ISO-8850-15', 'ISO-8850-16', 'CP1250', 'CP1251', 'CP1252', 'CP1253', 'CP1254',
'CP1257', 'CP850', 'CP866',
);
$obj = clone($source_obj);
for($i=0;$i<count($charset_list);$i++) {
$charset = $charset_list[$i];
$flag = true;
foreach($obj as $key=>$val) {
if(!$val) continue;
if($val && !iconv($charset,'UTF-8',$val)) $flag = false;
}
if($flag == true) {
foreach($obj as $key => $val) $obj->{$key} = iconv($charset,'UTF-8',$val);
return $obj;
}
}
}/*}}}*/
/**
* Request Method Argument의 설정 return
**/
// private void _setRequestMethod()/*{{{*/
// request method가 어떤것인지 판단하여 저장 (GET/POST/XMLRPC)
function _setRequestMethod() {
if($GLOBALS['HTTP_RAW_POST_DATA']) $this->request_method = "XMLRPC";
else $this->request_method = $_SERVER['REQUEST_METHOD'];
}/*}}}*/
// private void _setRequestArgument();/*{{{*/
// GET/POST방식일 경우 처리
function _setRequestArgument() {
if($this->_getRequestMethod() == 'XMLRPC') return;
if(!count($_REQUEST)) return;
foreach($_REQUEST as $key => $val) {
if(is_array($val)) {
for($i=0;$i<count($val);$i++) {
if(get_magic_quotes_gpc()) $val[$i] = stripslashes($val[$i]);
$val[$i] = trim($val[$i]);
}
} else {
if(get_magic_quotes_gpc()) $val = stripslashes($val);
$val = trim($val);
}
if(!$val) continue;
if($this->_getRequestMethod()=='GET'&&$_GET[$key]) $set_to_vars = true;
elseif($this->_getRequestMethod()=='POST'&&$_POST[$key]) $set_to_vars = true;
else $set_to_vars = false;
$this->_set($key, $val, $set_to_vars);
}
}/*}}}*/
// private void _setXmlRpcArgument()/*{{{*/
// XML RPC일때역시
function _setXmlRpcArgument() {
if($this->_getRequestMethod() != 'XMLRPC') return;
$oXml = new XmlParser();
$xml_obj = $oXml->parse();
$method_name = $xml_obj->methodcall->methodname->body;
$params = $xml_obj->methodcall->params;
unset($params->node_name);
unset($params->attrs);
if(!count($params)) return;
foreach($params as $key => $obj) {
$val = trim($obj->body);
$this->_set($key, $val, true);
}
}/*}}}*/
// public boolean isUploaded() /*{{{*/
// 업로드 되었을 경우 return true
function isUploaded() {
$oContext = &Context::getInstance();
return $oContext->_isUploaded();
}/*}}}*/
// private boolean isUploaded() /*{{{*/
// 업로드 되었을 경우 return true
function _isUploaded() {
return $this->is_uploaded;
}/*}}}*/
// private void _setUploadedArgument()/*{{{*/
// 업로드된 파일이 있을 경우도 역시 context에 통합 처리 (단 정상적인 업로드인지 체크)
function _setUploadedArgument() {
if($this->_getRequestMethod() != 'POST') return;
if(!eregi("^multipart\/form-data", $_SERVER['CONTENT_TYPE'])) return;
if(!$_FILES) return;
foreach($_FILES as $key => $val) {
$tmp_name = $val['tmp_name'];
if(!$tmp_name || !is_uploaded_file($tmp_name)) continue;
$this->_set($key, $val, true);
$this->is_uploaded = true;
}
}/*}}}*/
// public string getRequestMethod()/*{{{*/
// Request Method값을 return (GET/POST/XMLRPC);
function getRequestMethod() {
$oContext = &Context::getInstance();
return $oContext->_getRequestMethod();
}/*}}}*/
// private string _getRequestMethod()/*{{{*/
function _getRequestMethod() {
return $this->request_method;
}/*}}}*/
// public string getUrl($num_args, $args_list)/*{{{*/
// 요청받은 url에 args_list를 적용하여 return
function getUrl($num_args, $args_list) {
$oContext = &Context::getInstance();
return $oContext->_getUrl($num_args, $args_list);
}/*}}}*/
// private string _getUrl($num_args, $args_list)/*{{{*/
// 요청받은 url에 args_list를 적용하여 return
function _getUrl($num_args, $args_list) {
if(!is_object($this->get_vars)) $get_vars = null;
else $get_vars = clone($this->get_vars);
for($i=0;$i<$num_args;$i=$i+2) {
$key = $args_list[$i];
$val = $args_list[$i+1];
$get_vars->{$key} = trim($val);
}
$var_count = count(get_object_vars($get_vars));
if(!$var_count) return;
foreach($get_vars as $key => $val) {
if(!$val) continue;
$url_list[] = sprintf("%s=%s",$key, $val);
}
preg_match("/([a-zA-Z\_]+)\.php/i", $_SERVER['PHP_SELF'], $match);
$filename = $match[0];
if($filename == 'index.php') $filename = '';
return './'.$filename.'?'.htmlspecialchars(implode('&', $url_list));
}/*}}}*/
// public string getRequestUri() /*{{{*/
function getRequestUri() {
$hostname = $_SERVER['SERVER_NAME'];
$port = $_SERVER['SERVER_PORT'];
if($port!=80) $hostname .= ":{$port}";
$path = $_SERVER['REDIRECT_URL'];
$path = $_SERVER['REDIRECT_URL']?$_SERVER['REDIRECT_URL']:preg_replace('/([a-zA-Z0-9\_]+).php/i','',$_SERVER['PHP_SELF']);
return sprintf("http://%s%s",$hostname,$path);
}/*}}}*/
/**
* Request Argument외의 데이터 set/get
**/
// public void set($key, $val, $set_to_get_vars = false)/*{{{*/
// key/val 로 데이터 세팅
function set($key, $val, $set_to_get_vars = false) {
$oContext = &Context::getInstance();
$oContext->_set($key, $val, $set_to_get_vars);
}/*}}}*/
// private void _set($key, $val, $set_to_get_vars = false)/*{{{*/
function _set($key, $val, $set_to_get_vars = false) {
$this->context->{$key} = $val;
if($set_to_get_vars || $this->get_vars->{$key}) $this->get_vars->{$key} = $val;
}/*}}}*/
// public object get($key)/*{{{*/
// key값에 해당하는 값을 return
function get($key) {
$oContext = &Context::getInstance();
return $oContext->_get($key);
}/*}}}*/
// private object _get($key)/*{{{*/
function _get($key) {
return $this->context->{$key};
}/*}}}*/
// public object gets(void)/*{{{*/
// 받고자 하는 변수만 object에 입력하여 받음
function gets() {
$num_args = func_num_args();
if($num_args<1) return;
$args_list = func_get_args();
$oContext = &Context::getInstance();
return $oContext->_gets($num_args, $args_list);
}/*}}}*/
// private object _gets($args_list)/*{{{*/
function _gets($num_args, $args_list) {
for($i=0;$i<$num_args;$i++) {
$args = $args_list[$i];
$output->{$args} = $this->_get($args);
}
return $output;
}/*}}}*/
// public object getAll()/*{{{*/
// 모든 데이터를 return
function getAll() {
$oContext = &Context::getInstance();
return $oContext->_getAll();
}/*}}}*/
// private object _getAll()/*{{{*/
function _getAll() {
return $this->context;
}/*}}}*/
// public object getRequestVars()/*{{{*/
// GET/POST/XMLRPC에서 넘어온 변수값을 return
function getRequestVars() {
$oContext = &Context::getInstance();
return $oContext->_getRequestVars();
}/*}}}*/
// private object _getRequestVars()/*{{{*/
function _getRequestVars() {
return clone($this->get_vars);
}/*}}}*/
/**
* CSS/JS/HeaderText html을 출력할때 사용할 값들
**/
// public void addJsFile($file)/*{{{*/
// js file 추가
function addJsFile($file) {
$oContext = &Context::getInstance();
return $oContext->_addJsFile($file);
}/*}}}*/
// private void _addJsFile($file)/*{{{*/
function _addJsFile($file) {
if(in_array($file, $this->js_files)) return;
$this->js_files[] = $file;
}/*}}}*/
// public array getJsFile()/*{{{*/
function getJsFile() {
$oContext = &Context::getInstance();
return $oContext->_getJsFile();
}/*}}}*/
// private array _getJsFile()/*{{{*/
function _getJsFile() {
return $this->js_files;
}/*}}}*/
// public void addCSSFile($file)/*{{{*/
// CSS file 추가
function addCSSFile($file) {
$oContext = &Context::getInstance();
return $oContext->_addCSSFile($file);
}/*}}}*/
// private void _addCSSFile($file)/*{{{*/
function _addCSSFile($file) {
if(in_array($file, $this->css_files)) return;
$this->css_files[] = $file;
}/*}}}*/
// public array getCSSFile()/*{{{*/
// CSS file 추가
function getCSSFile() {
$oContext = &Context::getInstance();
return $oContext->_getCSSFile();
}/*}}}*/
// private array _getCSSFile()/*{{{*/
function _getCSSFile() {
return $this->css_files;
}/*}}}*/
// public void addHtmlHeader($file)/*{{{*/
// HtmlHeader 추가
function addHtmlHeader($file) {
$oContext = &Context::getInstance();
return $oContext->_addHtmlHeader($file);
}/*}}}*/
// private void _addHtmlHeader($file)/*{{{*/
function _addHtmlHeader($file) {
$this->HtmlHeader .= ($this->HtmlHeader?"\n":"").$file;
}/*}}}*/
// public string getHtmlHeader()/*{{{*/
// HtmlHeader 추가
function getHtmlHeader() {
$oContext = &Context::getInstance();
return $oContext->_getHtmlHeader();
}/*}}}*/
// private string _getHtmlHeader()/*{{{*/
function _getHtmlHeader() {
return $this->HtmlHeader;
}/*}}}*/
/**
* 인스톨 관련
**/
// public String getConfigFile()/*{{{*/
// db설정내용이 저장되어 있는 config file의 path를 return
function getConfigFile() {
return "./files/config/db.config.php";
}/*}}}*/
// public boolean isInstalled()/*{{{*/
// 설치가 되어 있는지에 대한 체크
function isInstalled() {
return file_exists(Context::getConfigFile());
}/*}}}*/
}
?>

237
classes/db/DB.class.php Normal file
View file

@ -0,0 +1,237 @@
<?php
/**
* @file : classes/db/DB.class.php
* @author : zero <zero@nzeo.com>
* @desc : DB* 상위 클래스
**/
class DB {
// connector resource or file description
var $fd = NULL;
// result
var $result = NULL;
// errno, errstr
var $errno = 0;
var $errstr = '';
var $query = '';
// isconnected
var $is_connected = false;
// 지원하는 DB의 종류
var $supported_list = array();
// public Object &getInstance($db_type)/*{{{*/
// DB를 상속받는 특정 db type의 instance를 생성 후 return
function &getInstance($db_type = NULL) {
if(!$db_type) $db_type = Context::getDBType();
if(!$db_type) return new Output(-1, 'msg_db_not_setted');
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);
if(!file_exists($class_file)) new Output(-1, 'msg_db_not_setted');
require_once($class_file);
$eval_str = sprintf('$GLOBALS[\'__DB__\'] = new %s();', $class_name);
eval($eval_str);
}
return $GLOBALS['__DB__'];
}/*}}}*/
/**
* 지원 가능한 DB 목록을 return
**/
// public array getSupportedList()/*{{{*/
// 지원하는 DB의 종류 return
function getSupportedList() {
$oDB = new DB();
return $oDB->_getSupportedList();
}/*}}}*/
// private array _getSupportedList()/*{{{*/
function _getSupportedList() {
if(!count($this->supported_list)) {
$db_classes_path = "./classes/db/";
$filter = "/^DB([^\.]+)\.class\.php/i";
$this->supported_list = FileHandler::readDir($db_classes_path, $filter, true);
}
return $this->supported_list;
}/*}}}*/
// public boolean isSupported($db_type) /*{{{*/
// 지원하는 DB인지에 대한 check
function isSupported($db_type) {
$supported_list = DB::getSupportedList();
return in_array($db_type, $supported_list);
}/*}}}*/
/**
* 에러 남기기
**/
// public void setError($errno, $errstr) /*{{{*/
function setError($errno, $errstr) {
$this->errno = $errno;
$this->errstr = $errstr;
if(__DEBUG__ && $this->errno!=0) debugPrint(sprintf("Query Fail\t#%05d : %s - %s\n\t\t%s", $GLOBALS['__dbcnt'], $errno, $errstr, $this->query));
}/*}}}*/
/**
* 각종 bool return
**/
// public boolean isConnected()/*{{{*/
// 접속되었는지 return
function isConnected() {
return $this->is_connected;
}/*}}}*/
// public boolean isError()/*{{{*/
// 오류가 발생하였는지 return
function isError() {
return $error===0?true:false;
}/*}}}*/
// public object getError()/*{{{*/
function getError() {
return new Output($this->errno, $this->errstr);
}/*}}}*/
/**
* query execute
**/
// public object executeQuery($query_id, $args = NULL)/*{{{*/
// query_id = module.queryname
// query_id에 해당하는 xml문(or 캐싱파일)을 찾아서 실행
function executeQuery($query_id, $args = NULL) {
if(!$query_id) return new Output(-1, 'msg_invalid_queryid');
list($module, $id) = explode('.',$query_id);
if(!$module||!$id) return new Output(-1, 'msg_invalid_queryid');
$xml_file = sprintf('./modules/%s/queries/%s.xml', $module, $id);
if(!file_exists($xml_file)) {
$xml_file = sprintf('./files/modules/%s/queries/%s.xml', $module, $id);
if(!file_exists($xml_file)) return new Output(-1, 'msg_invalid_queryid');
}
// 일단 cache 파일을 찾아본다
$cache_file = sprintf('./files/queries/%s.cache.php', $query_id);
// 없으면 원본 쿼리 xml파일을 찾아서 파싱을 한다
if(!file_exists($cache_file)||filectime($cache_file)<filectime($xml_file)) {
require_once('./classes/xml/XmlQueryParser.class.php');
$oParser = new XmlQueryParser();
$oParser->parse($query_id, $xml_file, $cache_file);
}
// 쿼리를 실행한다
return $this->_executeQuery($cache_file, $args, $query_id);
}/*}}}*/
// private object _executeQuery($cache_file, $args)/*{{{*/
// 쿼리문을 실행하고 결과를 return한다
function _executeQuery($cache_file, $source_args, $query_id) {
global $lang;
if(!file_exists($cache_file)) return new Output(-1, 'msg_invalid_queryid');
if(__DEBUG__) $query_start = getMicroTime();
if($source_args) $args = clone($source_args);
$output = include($cache_file);
if( (is_a($output, 'Output')||is_subclass_of($output,'Output'))&&!$output->toBool()) return $output;
// action값에 따라서 쿼리 생성으로 돌입
switch($action) {
case 'insert' :
$output = $this->_executeInsertAct($tables, $column, $pass_quotes);
break;
case 'update' :
$output = $this->_executeUpdateAct($tables, $column, $condition, $pass_quotes);
break;
case 'delete' :
$output = $this->_executeDeleteAct($tables, $condition, $pass_quotes);
break;
case 'select' :
$output = $this->_executeSelectAct($tables, $column, $invert_columns, $condition, $navigation, $group_script, $pass_quotes);
break;
}
if(__DEBUG__) {
$query_end = getMicroTime();
$elapsed_time = $query_end - $query_start;
$GLOBALS['__db_elapsed_time__'] += $elapsed_time;
$GLOBALS['__db_queries__'] .= sprintf("\t%02d. %s (%0.4f sec)\n\t %s\n", ++$GLOBALS['__dbcnt'], $query_id, $elapsed_time, $this->query);
}
if($this->errno!=0) return new Output($this->errno, $this->errstr);
if(is_a($output, 'Output') || is_subclass_of($output, 'Output')) return $output;
return new Output();
}/*}}}*/
// private object _checkFilter($key, $val, $filter_type, $minlength, $maxlength) /*{{{*/
// $val을 $filter_type으로 검사
function _checkFilter($key, $val, $filter_type, $minlength, $maxlength) {
global $lang;
$length = strlen($val);
if($minlength && $length < $minlength) return new Output(-1, sprintf($lang->filter->outofrange, $lang->{$key}?$lang->{$key}:$key));
if($maxlength && $length > $maxlength) return new Output(-1, sprintf($lang->filter->outofrange, $lang->{$key}?$lang->{$key}:$key));
switch($filter_type) {
case 'email' :
case 'email_adderss' :
if(!eregi('^[_0-9a-z-]+(\.[_0-9a-z-]+)*@[0-9a-z-]+(\.[0-9a-z-]+)*$', $val)) return new Output(-1, sprintf($lang->filter->invalid_email, $lang->{$key}?$lang->{$key}:$key));
break;
case 'homepage' :
if(!eregi('^(http|https)+(:\/\/)+[0-9a-z_-]+\.[^ ]+$', $val)) return new Output(-1, sprintf($lang->filter->invalid_homepage, $lang->{$key}?$lang->{$key}:$key));
break;
case 'userid' :
case 'user_id' :
if(!eregi('^[a-zA-Z]+([_0-9a-zA-Z]+)*$', $val)) return new Output(-1, sprintf($lang->filter->invalid_userid, $lang->{$key}?$lang->{$key}:$key));
break;
case 'number' :
if(!eregi('^[0-9]+$', $val)) return new Output(-1, sprintf($lang->filter->invalid_number, $lang->{$key}?$lang->{$key}:$key));
break;
case 'alpha' :
if(!eregi('^[a-z]+$', $val)) return new Output(-1, sprintf($lang->filter->invalid_alpha, $lang->{$key}?$lang->{$key}:$key));
break;
case 'alpha_number' :
if(!eregi('^[0-9a-z]+$', $val)) return new Output(-1, sprintf($lang->filter->invalid_alpha_number, $lang->{$key}?$lang->{$key}:$key));
break;
}
return new Output();
}/*}}}*/
// private string _combineCondition($cond_group, $group_pipe) /*{{{*/
function _combineCondition($cond_group, $group_pipe) {
if(!is_array($cond_group)) return;
$cond_query = '';
foreach($cond_group as $group_idx => $group) {
if(!is_array($group)) continue;
$buff = '';
foreach($group as $key => $val) {
$pipe = key($val);
$cond = array_pop($val);
if($buff) $buff .= $pipe.' '.$cond;
else $buff = $cond;
}
$g_pipe = $group_pipe[$group_idx];
if(!$g_pipe) $g_pipe = 'and';
if($cond_query) $cond_query .= sprintf(' %s ( %s )', $g_pipe, $buff);
else $cond_query = '('.$buff.')';
}
return $cond_query;
}/*}}}*/
}
?>

View file

@ -0,0 +1,375 @@
<?php
/**
* @file : classes/db/DB.class.php
* @author : zero <zero@nzeo.com>
* @desc : db(mysql, cubrid, sqlite..) 이용하기 위한 db class의 abstract class
**/
class DBMysql extends DB {
// db info
var $hostname = '127.0.0.1';
var $userid = NULL;
var $password = NULL;
var $database = NULL;
var $prefix = 'zb';
// mysql에서 사용될 column type
var $column_type = array(
'number' => 'int',
'varchar' => 'varchar',
'char' => 'char',
'text' => 'text',
'date' => 'varchar(14)',
);
// public void DBMysql()/*{{{*/
function DBMysql() {
$this->_setDBInfo();
$this->_connect();
}/*}}}*/
/**
* DB정보 설정 connect/ close
**/
// public boolean _setDBInfo()/*{{{*/
function _setDBInfo() {
$db_info = Context::getDBInfo();
$this->hostname = $db_info->db_hostname;
$this->userid = $db_info->db_userid;
$this->password = $db_info->db_password;
$this->database = $db_info->db_database;
$this->prefix = $db_info->db_table_prefix;
if(!substr($this->prefix,-1)!='_') $this->prefix .= '_';
}/*}}}*/
// public boolean _connect()/*{{{*/
function _connect() {
// db 정보가 없으면 무시
if(!$this->hostname || !$this->userid || !$this->password || !$this->database) return;
// 접속시도
$this->fd = @mysql_connect($this->hostname, $this->userid, $this->password);
if(mysql_error()) {
$this->setError(mysql_errno(), mysql_error());
return;
}
// db 선택
@mysql_select_db($this->database, $this->fd);
if(mysql_error()) {
$this->setError(mysql_errno(), mysql_error());
return;
}
// 접속체크
$this->is_connected = true;
// mysql의 경우 utf8임을 지정
$this->_query("SET NAMES 'utf8'");
}/*}}}*/
// public boolean close()/*{{{*/
function close() {
if(!$this->isConnected()) return;
@mysql_close($this->fd);
}/*}}}*/
/**
* add quotation
**/
// public string addQuotes(string $string)/*{{{*/
function addQuotes($string) {
if(get_magic_quotes_gpc()) $string = stripslashes(str_replace("\\","\\\\",$string));
if(!is_numeric($string)) $string = @mysql_escape_string($string);
return $string;
}/*}}}*/
/**
* query : query문 실행하고 result return
* fetch : reutrn 값이 없으면 NULL
* rows이면 array object
* row이면 object
* return
* getNextSequence : 1 증가되는 sequence값을 return (mysql의 auto_increment는 sequence테이블에서만 사용)
*/
// private object _query(string $query) /*{{{*/
function _query($query) {
if(!$this->isConnected()) return;
$this->query = $query;
$this->setError(0,'success');
$result = @mysql_query($query, $this->fd);
if(mysql_error()) {
$this->setError(mysql_errno(), mysql_error());
return;
}
return $result;
}/*}}}*/
// private object _fetch($result) /*{{{*/
function _fetch($result) {
if($this->errno!=0 || !$result) return;
while($tmp = mysql_fetch_object($result)) {
$output[] = $tmp;
}
if(count($output)==1) return $output[0];
return $output;
}/*}}}*/
// public int getNextSequence() /*{{{*/
// sequence값을 받음
function getNextSequence() {
$query = sprintf("insert into `%ssequence` (seq) values ('')", $this->prefix);
$this->_query($query);
return mysql_insert_id();
}/*}}}*/
/**
* Table의 Create/Drop/Alter/Rename/Truncate/Dump...
**/
// public boolean isTableExists(string $table_name)/*{{{*/
function isTableExists($target_name) {
$query = sprintf("show tables like '%s%s'", $this->prefix, $this->addQuotes($target_name));
$result = $this->_query($query);
$tmp = $this->_fetch($result);
if(!$tmp) return false;
return true;
}/*}}}*/
// public boolean createTableByXml($xml) /*{{{*/
// xml 을 받아서 테이블을 생성
function createTableByXml($xml_doc) {
return $this->_createTable($xml_doc);
}/*}}}*/
// public boolean createTableByXmlFile($file_name) /*{{{*/
// xml 을 받아서 테이블을 생성
function createTableByXmlFile($file_name) {
if(!file_exists($file_name)) return;
// xml 파일을 읽음
$buff = FileHandler::readFile($file_name);
return $this->_createTable($buff);
}/*}}}*/
// private boolean _createTable($xml)/*{{{*/
// type : number, varchar, text, char, date,
// opt : notnull, default, size
// index : primary key, index, unique
function _createTable($xml_doc) {
// xml parsing
$oXml = new XmlParser();
$xml_obj = $oXml->parse($xml_doc);
// 테이블 생성 schema 작성
$table_name = $xml_obj->table->attrs->name;
if($this->isTableExists($table_name)) return;
$table_name = $this->prefix.$table_name;
if(!is_array($xml_obj->table->column)) $columns[] = $xml_obj->table->column;
else $columns = $xml_obj->table->column;
foreach($columns as $column) {
$name = $column->attrs->name;
$type = $column->attrs->type;
$size = $column->attrs->size;
$notnull = $column->attrs->notnull;
$primary_key = $column->attrs->primary_key;
$index = $column->attrs->index;
$unique = $column->attrs->unique;
$default = $column->attrs->default;
$auto_increment = $column->attrs->auto_increment;
$column_schema[] = sprintf('`%s` %s%s %s %s %s',
$name,
$this->column_type[$type],
$size?'('.$size.')':'',
$default?"default '".$default."'":'',
$notnull?'not null':'',
$auto_increment?'auto_increment':''
);
if($primary_key) $primary_list[] = $name;
else if($unique) $unique_list[$unique][] = $name;
else if($index) $index_list[$index][] = $name;
}
if(count($primary_list)) {
$column_schema[] = sprintf("primary key (%s)", '`'.implode($primary_list,'`,`').'`');
}
if(count($unique_list)) {
foreach($unique_list as $key => $val) {
$column_schema[] = sprintf("unique %s (%s)", $key, '`'.implode($val,'`,`').'`');
}
}
if(count($index_list)) {
foreach($index_list as $key => $val) {
$column_schema[] = sprintf("index %s (%s)", $key, '`'.implode($val,'`,`').'`');
}
}
$schema = sprintf('create table `%s` (%s%s);', $this->addQuotes($table_name), "\n", implode($column_schema,",\n"));
$output = $this->_query($schema);
if(!$output) return false;
}/*}}}*/
// public boolean dropTable($target_name) /*{{{*/
// 테이블 삭제
function dropTable($target_name) {
$query = sprintf('drop table `%s%s`;', $this->prefix, $this->addQuotes($target_name));
$this->_query($query);
}/*}}}*/
// public boolean renameTable($source_name, $targe_name) /*{{{*/
// 테이블의 이름 변경
function renameTable($source_name, $targe_name) {
$query = sprintf("alter table `%s%s` rename `%s%s`;", $this->prefix, $this->addQuotes($source_name), $this->prefix, $this->addQuotes($targe_name));
$this->_query($query);
}/*}}}*/
// public boolean truncateTable($target_name) /*{{{*/
// 테이블을 비움
function truncateTable($target_name) {
$query = sprintf("truncate table `%s%s`;", $this->prefix, $this->addQuotes($target_name));
$this->_query($query);
}/*}}}*/
// public boolean dumpTable($target_name) 미완성 /*{{{*/
// 테이블 데이터 Dump
function dumpTable($target_name) {
}/*}}}*/
/**
* insert/update/delete/select 구현
**/
// private string _executeInsertAct($tables, $column, $pass_quotes)/*{{{*/
function _executeInsertAct($tables, $column, $pass_quotes) {
$table = array_pop($tables);
foreach($column as $key => $val) {
$key_list[] = $key;
if(in_array($key, $pass_quotes)) $val_list[] = $this->addQuotes($val);
else $val_list[] = '\''.$this->addQuotes($val).'\'';
}
$query = sprintf("insert into `%s%s` (%s) values (%s);", $this->prefix, $table, '`'.implode('`,`',$key_list).'`', implode(',', $val_list));
return $this->_query($query);
}/*}}}*/
// private string _executeUpdateAct($tables, $column, $condition, $pass_quotes)/*{{{*/
function _executeUpdateAct($tables, $column, $condition, $pass_quotes) {
$table = array_pop($tables);
foreach($column as $key => $val) {
if(in_array($key, $pass_quotes)) $update_list[] = sprintf('`%s` = %s', $key, $this->addQuotes($val));
else $update_list[] = sprintf('`%s` = \'%s\'', $key, $this->addQuotes($val));
}
if(!count($update_list)) return;
$update_query = implode(',',$update_list);
if($condition) $condition = ' where '.$condition;
$query = sprintf("update `%s%s` set %s %s;", $this->prefix, $table, $update_query, $condition);
return $this->_query($query);
}/*}}}*/
// private string _executeDeleteAct($tables, $condition, $pass_quotes)/*{{{*/
function _executeDeleteAct($tables, $condition, $pass_quotes) {
$table = array_pop($tables);
if($condition) $condition = ' where '.$condition;
$query = sprintf("delete from `%s%s` %s;", $this->prefix, $table, $condition);
return $this->_query($query);
}/*}}}*/
// private string _executeSelectAct($tables, $column, $invert_columns, $condition, $navigation, $pass_quotes)/*{{{*/
// 네비게이션 변수 정리를 해야함
function _executeSelectAct($tables, $column, $invert_columns, $condition, $navigation, $group_script, $pass_quotes) {
if(!count($tables)) $table = $this->prefix.array_pop($tables);
else {
foreach($tables as $key => $val) $table_list[] = sprintf('%s%s as %s', $this->prefix, $key, $val);
}
$table = implode(',',$table_list);
if(!$column) $columns = '*';
else {
foreach($invert_columns as $key => $val) {
$column_list[] = sprintf('%s as %s',$val, $key);
}
$columns = implode(',', $column_list);
}
if($condition) $condition = ' where '.$condition;
if($navigation->list_count) return $this->_getNavigationData($table, $columns, $condition, $navigation);
$query = sprintf("select %s from %s %s", $columns, $table, $condition);
$query .= ' '.$group_script;
if($navigation->index) {
foreach($navigation->index as $index_obj) {
$index_list[] = sprintf('%s %s', $index_obj[0], $index_obj[1]);
}
if(count($index_list)) $query .= ' order by '.implode(',',$index_list);
}
$result = $this->_query($query);
if($this->errno!=0) return;
$data = $this->_fetch($result);
$buff = new Output();
$buff->data = $data;
return $buff;
}/*}}}*/
// private function _getNavigationData($query)/*{{{*/
// query xml에 navigation 정보가 있을 경우 페이징 관련 작업을 처리한다
// 그닥 좋지는 않은 구조이지만 편리하다.. -_-;
function _getNavigationData($table, $columns, $condition, $navigation) {
// 전체 개수를 구함
$count_query = sprintf("select count(*) as count from %s %s", $table, $condition);
$result = $this->_query($count_query);
$count_output = $this->_fetch($result);
$total_count = (int)$count_output->count;
// 전체 페이지를 구함
$total_page = (int)(($total_count-1)/$navigation->list_count) +1;
// 페이지 변수를 체크
if($navigation->page > $total_page) $page = $navigation->page;
else $page = $navigation->page;
$start_count = ($page-1)*$navigation->list_count;
foreach($navigation->index as $index_obj) {
$index_list[] = sprintf('%s %s', $index_obj[0], $index_obj[1]);
}
$index = implode(',',$index_list);
$query = sprintf('select %s from %s %s order by %s limit %d, %d', $columns, $table, $condition, $index, $start_count, $navigation->list_count);
$result = $this->_query($query);
if($this->errno!=0) return;
$virtual_no = $total_count - ($page-1)*$navigation->list_count;
while($tmp = mysql_fetch_object($result)) {
$data[$virtual_no--] = $tmp;
}
$buff = new Output();
$buff->total_count = $total_count;
$buff->total_page = $total_page;
$buff->page = $page;
$buff->data = $data;
require_once('./classes/page/PageHandler.class.php');
$buff->page_navigation = new PageHandler($total_count, $total_page, $page, $navigation->page_count);
return $buff;
}/*}}}*/
}
?>

View file

@ -0,0 +1,154 @@
<?php
/**
* @file : classes/display/DisplayHandler.class.php
* @author : zero <zero@nzeo.com>
* @desc : display 객체
* Request Method에 따라서 html or xml 출력방법을 결정한다
* xml : oModule의 variables를 simple xml 출력
* html : oModule의 template/variables로 html을 만들고 contents_html로 처리
* plugin이나 layout의 html과 연동하여 출력
*
**/
class DisplayHandler {
// 출력하는 컨텐츠의 사이즈
var $content_size = 0;
// public void printContent() /*{{{*/
function printContent($oModule) {
// header 출력
$this->_printHeader();
// request method에 따른 처리
$content = $this->getContent($oModule);
// 요청방식에 따라 출력을 별도로
if(Context::getRequestMethod()!="XMLRPC") {
Context::set('content', $content);
// content 래핑 (common/tpl/default.html)
require_once("./classes/template/TemplateHandler.class.php");
$oTemplate = new TemplateHandler();
$output = $oTemplate->compile($oModule->layout_path, $oModule->layout_tpl);
} else {
$output = $content;
}
$this->content_size = strlen($output);
print $output;
// 디버깅 데이터 출력
$this->_debugOutput();
}/*}}}*/
// public void getContent() /*{{{*/
function getContent($oModule) {
// request method에 따른 처리
return $this->_toDoc($oModule);
}/*}}}*/
/**
* 문서 출력
**/
// private string _toDoc($oModule) /*{{{*/
function _toDoc($oModule) {
if(Context::getRequestMethod() == 'XMLRPC') $content = $this->_toXmlDoc($oModule);
else $content = $this->_toHTMLDoc($oModule);
return $content;
}/*}}}*/
// private string _toXmlDoc($oModule) /*{{{*/
function _toXmlDoc($oModule) {
$xmlDoc = "<response>\n";
$xmlDoc .= sprintf("<error>%s</error>\n",$oModule->getError());
$xmlDoc .= sprintf("<message>%s</message>\n",$oModule->getMessage());
$variables = $oModule->getVariables();
if(count($variables)) {
foreach($variables as $key => $val) {
if(is_string($val)) $val = '<![CDATA['.$val.']]>';
$xmlDoc .= "<{$key}>{$val}</{$key}>\n";
}
}
$xmlDoc .= "</response>";
return $xmlDoc;
}/*}}}*/
// private string _toHTMLDoc($oModule) /*{{{*/
function _toHTMLDoc($oModule) {
// template handler 객체 생성
require_once("./classes/template/TemplateHandler.class.php");
$oTemplate = new TemplateHandler();
// module tpl 변환
$template_path = $oModule->getTemplatePath();
$tpl_file = $oModule->getTemplateFile();
return $oTemplate->compile($template_path, $tpl_file);
}/*}}}*/
// public int getContentSize() /*{{{*/
function getContentSize() {
return $this->content_size;
}/*}}}*/
// private void _debugOutput()/*{{{*/
// __DEBUG__가 true일 경우 각 부분의 실행시간등을 debugPrint 함수를 이용해서 출력
// 개발시나 테스트시에 config/config.inc.php의 __DEBUG__를 true로 세팅하고
// tail -f ./files/_debug_message.php로 하여 console로 확인하면 편리함
function _debugOutput() {
if(!__DEBUG__) return;
$end = getMicroTime();
$buff = "\n\n** Debug at ".date('Y-m-d H:i:s')." ************************************************************\n";
$buff .= "\n- Request/ Response info\n";
$buff .= sprintf("\tRequest URI \t\t\t: %s:%s%s%s%s\n", $_SERVER['SERVER_NAME'], $_SERVER['SERVER_PORT'], $_SERVER['PHP_SELF'], $_SERVER['QUERY_STRING']?'?':'', $_SERVER['QUERY_STRING']);
$buff .= sprintf("\tRequest method \t\t\t: %s\n", $_SERVER['REQUEST_METHOD']);
$buff .= sprintf("\tResponse contents size\t\t: %d byte\n", $this->getContentSize());
if($GLOBALS['__db_queries__']) {
$buff .= "\n- DB Queries\n";
$buff .= $GLOBALS['__db_queries__'];
}
$buff .= "\n- Elapsed time\n";
if($GLOBALS['__db_elapsed_time__']) $buff .= sprintf("\tDB queries elapsed time\t\t: %0.5f sec\n", $GLOBALS['__db_elapsed_time__']);
$buff .= sprintf("\tclass file load elapsed time \t: %0.5f sec\n", __RequireClassEndTime__-__RequireClassStartTime__);
$buff .= sprintf("\tTemplate compile elapsed time\t: %0.5f sec\n", $GLOBALS['__template_elapsed__']);
$buff .= sprintf("\tPHP elapsed time \t\t: %0.5f sec\n", $end-__StartTime__-$GLOBALS['__template_elapsed__']-$GLOBALS['__db_elapsed_time__']-(__RequireClassEndTime__-__RequireClassStartTime__));
$buff .= sprintf("\tTotal elapsed time \t\t: %0.5f sec", $end-__StartTime__);
debugPrint($buff, false);
}/*}}}*/
/**
* 헤더 출력
***/
// private void _printHeader()/*{{{*/
function _printHeader() {
if(Context::getRequestMethod() == 'XMLRPC') return $this->_printXMLHeader();
else return $this->_printHTMLHeader();
}/*}}}*/
// private void _printXMLHeader()/*{{{*/
function _printXMLHeader() {
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");
}/*}}}*/
// private void _printHTMLHeader()/*{{{*/
function _printHTMLHeader() {
header("Content-Type: text/html; 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");
}/*}}}*/
}
?>

View file

@ -0,0 +1,94 @@
<?php
/**
* @file : classes/file/FileHandler.class.php
* @author : zero <zero@nzeo.com>
* @desc : 파일 시스템 관련 라이브러리
**/
class FileHandler {
// public String readFile()/*{{{*/
function readFile($file_name) {
if(!file_exists($file_name)) return;
if(filesize($file_name)<1) return;
$fp = fopen($file_name, "r");
$buff = fread($fp, filesize($file_name));
fclose($fp);
return trim($buff);
}/*}}}*/
// public String writeFile($file_name, $buff, $mode = "w")/*{{{*/
function writeFile($file_name, $buff, $mode = "w") {
$mode = strtolower($mode);
if($mode != "a") $mode = "w";
if(@!$fp = fopen($file_name,$mode)) return;
fwrite($fp, $buff);
fclose($fp);
}/*}}}*/
// public array readDir($path, $filter = '', $to_lower = flase)/*{{{*/
// $path내의 파일들을 return ('.', '..', '.로 시작하는' 파일들은 제외)
function readDir($path, $filter = '', $to_lower = false, $concat_prefix = false) {
if(substr($path,-1)!='/') $path .= '/';
if(!is_dir($path)) return array();
$oDir = dir($path);
while($file = $oDir->read()) {
if(substr($file,0,1)=='.') continue;
if($filter && !preg_match($filter, $file)) continue;
if($to_lower) $file = strtolower($file);
if($filter) $file = preg_replace($filter, '$1', $file);
else $file = $file;
if($concat_prefix) $file = $path.$file;
$output[] = $file;
}
if(!$output) return array();
return $output;
}/*}}}*/
// public boolean makeDir($path) {/*{{{*/
// 디렉토리 생성
function makeDir($path_string) {
$path_list = explode('/', $path_string);
for($i=0;$i<count($path_list);$i++) {
$path .= $path_list[$i].'/';
if(!is_dir($path)) {
@mkdir($path, 0707);
@chmod($path, 0707);
}
}
return is_dir($path_string);
}/*}}}*/
// public void removeDir($path) /*{{{*/
// 지정된 디렉토리 이하 모두 파일을 삭제
function removeDir($path) {
if(!is_dir($path)) return;
$directory = dir($path);
while($entry = $directory->read()) {
if ($entry != "." && $entry != "..") {
if (is_dir($path."/".$entry)) {
FileHandler::removeDir($path."/".$entry);
} else {
@unlink($path."/".$entry);
}
}
}
$directory->close();
@rmdir($path);
}/*}}}*/
// public string filesize($size) /*{{{*/
// byte단위의 파일크기를 적절하게 변환해서 return
function filesize($size) {
if(!$size) return "0Byte";
if($size<1024) return ($size."Byte");
if($size >1024 && $size< 1024 *1024) return sprintf("%0.1fKB",$size / 1024);
return sprintf("%0.2fMB",$size / (1024*1024));
}/*}}}*/
}
?>

View file

@ -0,0 +1,45 @@
<?php
/**
* @file : classes/layout/LayoutHandler.class.php
* @author : zero <zero@nzeo.com>
* @desc : layout 실행
**/
class LayoutHandler {
var $layout_info;
var $layout_name;
function callLayout(&$oModule, $oModuleInfo) {
if($oModule->getActType() != 'disp') return;
if(!$oModuleInfo->isLayoutExists()) return;
$oLayout = new LayoutHandler();
$oLayout->proc($oModule, $oModuleInfo);
}
function proc(&$oModule, $oModuleInfo) {
$this->layout_info = $oModuleInfo->getLayout();
$this->layout_name = $this->layout_info->layout_name;
$this->layout_name = 'test';
// 해당 모듈을 읽어서 객체를 만듬
$layout_file = sprintf('./layouts/%s/%s.layout.php', $this->layout_name, $this->layout_name);
// 모듈 파일이 없으면 에러
if(!file_exists($layout_file)) return;
// 모듈 파일을 include
require_once($layout_file);
// 선택된 모듈의 instance는 eval string으로 처리
$eval_str = sprintf('$oLayout = new %s();', $this->layout_name);
eval($eval_str);
// 애드온 실행
$oLayout->proc($oModule, $oModuleInfo);
}
}
?>

View file

@ -0,0 +1,132 @@
<?php
/**
* @file : classes/module/Module.class.php
* @author : zero <zero@nzeo.com>
* @desc : modules의 abstract class
**/
// abstract class Module
class Module extends Output {
// 현재 모듈의 실행 위치
var $module_path = NULL;
// skin 설정 (없을 경우도 있음)
var $skin = 'default';
// 현재 모듈 생성시 주어진 설정 정보들
var $module_srl = NULL;
var $module_info = NULL;
// 모듈의 action을 정의하는 변수 설정
var $act = NULL;
var $act_type = 'disp';
// 레이아웃 path, tpl
var $layout_path = "./common/tpl/";
var $layout_tpl = "default_layout";
// public void moduleInit($module_info)/*{{{*/
// 모듈의 정보 세팅
function moduleInit($module_info) {
// 브라우저 타이틀 지정
Context::setBrowserTitle($module_info->browser_title?$module_info->browser_title:$module_info->mid);
// 기본 변수 설정
$this->module_info = $module_info;
context::set('module_info', &$this->module_info);
$this->module_srl = $module_info->module_srl;
// skin 설정 (기본으로는 default)
if($this->module_info->skin) $this->skin = $this->module_info->skin;
else $this->skin = 'default';
// 템플릿 위치 설정
if(!$this->template_path) {
$template_path = $this->module_path.'skins/'.$this->skin;
$this->setTemplatePath($template_path);
}
}/*}}}*/
// public boolean isExistsAct($act)/*{{{*/
// 현재 모듈에 $act에 해당하는 method가 있는지 체크
function isExistsAct($act) {
return method_exists($this, $act);
}/*}}}*/
// public String getActType()/*{{{*/
// 현재 acT_type의 return (disp/proc)
function getActType() {
return $this->act_type;
}/*}}}*/
// public void setModulePath($path)/*{{{*/
// 현재 모듈의 path를 지정
function setModulePath($path) {
if(substr($path,-1)!='/') $path.='/';
$this->module_path = $path;
}/*}}}*/
// public boolean doError($msg_code) /*{{{*/
function doError($msg_code) {
$this->setError(-1);
if(!Context::getLang($msg_code)) $this->setMessage($msg_code);
else $this->setMessage(Context::getLang($msg_code));
return false;
}/*}}}*/
// public void setLayoutPath($path)/*{{{*/
function setLayoutPath($path) {
$this->layout_path = $path;
}/*}}}*/
// public void setLayoutTpl($tpl)/*{{{*/
function setLayoutTpl($tpl) {
$this->layout_tpl = $tpl;
}/*}}}*/
// public void proc($act = null)/*{{{*/
//모듈의 각 action을 실행하는 부분
//$act값에 의해서 $action_list에 선언된 것들을 실행한다
function proc($act = null) {
// 별도로 요청한 act가 없으면 주어진 act를 이용
if($act) $this->act = $act;
else $this->act = Context::get('act');
// act의 종류가 disp/proc인지에 대한 확인
if($this->act&&strtolower(substr($this->act,0,4)) != 'disp') $this->act_type = 'proc';
// act값이 없거나 존재하지 않는 method를 호출시에 default_act를 지정
if(!$this->act || !$this->isExistsAct($this->act)) $this->act = $this->default_act;
// module의 *init 호출 (기본 init과 proc/disp init 2가지 있음)
if($this->act_type == 'proc') {
$output = $this->procInit();
if((is_a($output, 'Output') || is_subclass_of($output, 'Output')) && !$output->toBool() ) {
$this->setError($output->getError());
$this->setMessage($output->getMessage());
return;
} elseif(!$output) {
$this->setError(-1);
$this->setMessage('fail');
return;
}
} else $this->dispInit();
// 기본 act조차 없으면 return
if(!$this->isExistsAct($this->act)) return false;
// act값으로 method 실행
$output = call_user_method($this->act, $this);
if(is_a($output, 'Output') || is_subclass_of($output, 'Output')) {
$this->setError($output->getError());
$this->setMessage($output->getMessage());
}
return true;
}/*}}}*/
}
?>

View file

@ -0,0 +1,87 @@
<?php
/**
* @file : classes/module/ModuleHandler.class.php
* @author : zero <zero@nzeo.com>
* @desc : mid의 값으로 모듈을 찾고 관련 정보들을 세팅
**/
class ModuleHandler {
// mid와 해당 mid의 설정 값
var $mid = NULL;
var $module_info = NULL;
// 모듈과 해당 모듈의 instance
var $module = NULL;
var $oModule = NULL;
// public void ModuleHandler()/*{{{*/
function ModuleHandler() {
// 설치가 안되어 있다면 설치를 위한 준비
if(!Context::isInstalled()) return $this->_prepareInstall();
// 설치가 되어 있다면 요청받은 mid에 해당하는 모듈 instance 생성
// mid가 없이 document_srl만 있다면 document_srl로 mid를 찾음
$mid = Context::get('mid');
$document_srl = Context::get('document_srl');
// document_srl만 있다면 mid를 구해옴
if(!$mid && $document_srl) {
$module_info = module_manager::getModuleInfoByDocument($document_srl);
if($module_info) $mid = $module_info->mid;
}
// mid 값에 대한 모듈 정보를 추출
if(!$module_info) $module_info = module_manager::getModuleInfo($mid);
// 모듈 정보에서 module 이름을 구해움
$module = $module_info->module;
$this->mid = $module_info->mid;
$this->module_info = $module_info;
Context::set('module', $module);
Context::set('mid', $this->mid, true);
Context::set('module_srl', $this->module_info->module_srl, true);
// 만약 모듈이 없다면 오류 출력
if(!$module) return $this->_moduleIsNotExists();
$this->oModule = getModule($module);
$this->module = $module;
}/*}}}*/
// private void _prepareInstall()/*{{{*/
// 설치를 하기 위해서 mid, module등을 강제 지정
function _prepareInstall() {
// module로 install 모듈을 지정
$this->module = 'install';
Context::set('mid', NULL);
Context::set('module', $this->module);
// module_manager 호출
$this->oModule = getModule($this->module);
}/*}}}*/
// private void _moduleIsNotExists()/*{{{*/
// 아무런 설정이 되어 있지 않다면 오류 표시
function _moduleIsNotExists() {
$this->module = 'message';
Context::set('mid', NULL);
Context::set('module', $this->module);
$this->oModule = getModule($this->module);
Context::set('error', -1);
Context::set('message', Context::getLang('msg_mid_not_exists'));
}/*}}}*/
// public object proc()/*{{{*/
function proc() {
$this->oModule->moduleInit($this->module_info);
$this->oModule->proc();
return $this->oModule;
}/*}}}*/
}
?>

View file

@ -0,0 +1,110 @@
<?php
/**
* @file : classes/output/Output.class.php
* @author : zero <zero@nzeo.com>
* @desc : result 객체
* request method에 따라서 error+message+variables[] xml문서로
* 또는 html 출력을
* 또는 사용법에 따라 error로 결과를 리턴한다
* error != 0 이면 에러가 발생하였다는 것으로 정의
**/
class Output {
// template path 지정
var $template_path = NULL;
var $template_file = NULL;
// 기본 에러와 메세지
var $error = 0;
var $message = 'success';
// 추가 변수
var $variables = array();
// public void Output($error = 0, $message = 'success')/*{{{*/
// error 코드를 지정
function Output($error = 0, $message = 'success') {
$this->error = $error;
$this->message = $message;
}/*}}}*/
// public void setError($error)/*{{{*/
// error 코드를 지정
function setError($error = 0) {
$this->error = $error;
}/*}}}*/
// public string getError()/*{{{*/
function getError() {
return $this->error;
}/*}}}*/
// public void setMessage($message)/*{{{*/
// 메세지 지정
function setMessage($message = 'success') {
if(Context::getLang($message)) $message = Context::getLang($message);
$this->message = $message;
return true;
}/*}}}*/
// public string getMessage()/*{{{*/
// 메세지 지정
function getMessage() {
return $this->message;
}/*}}}*/
// public void add($key, $val)/*{{{*/
// xml문서를 작성시 필요한 key, val 추가
function add($key, $val) {
$this->variables[$key] = $val;
}/*}}}*/
// public string get($key)/*{{{*/
// 추가된 변수의 key에 해당하는 값을 return
function get($key) {
return $this->variables[$key];
}/*}}}*/
// public array getVariables()/*{{{*/
// 설정된 variables를 return
function getVariables() {
return $this->variables;
}/*}}}*/
// public boolean toBool()/*{{{*/
// error값이 0이 아니면 오류
function toBool() {
return $this->error==0?true:false;
}/*}}}*/
// public boolean toBoolean()/*{{{*/
// error값이 0이 아니면 오류
function toBoolean() {
return $this->toBool();
}/*}}}*/
// public void setTemplatePath($path)/*{{{*/
// 현재 모듈의 tpl 파일을 저장
function setTemplatePath($path) {
if(!substr($path,-1)!='/') $path .= '/';
$this->template_path = $path;
}/*}}}*/
// public string getTemplatePath()/*{{{*/
// 설정된 template path를 return
function getTemplatePath() {
return $this->template_path;
}/*}}}*/
// public void setTemplateFile($filename)/*{{{*/
function setTemplateFile($filename) {
$this->template_file = $filename;
}/*}}}*/
// public string getTemplateFile()/*{{{*/
function getTemplateFile() {
return $this->template_file;
}/*}}}*/
}
?>

View file

@ -0,0 +1,42 @@
<?php
/**
* @file : classes/page/PageHandler.class.php
* @author : zero <zero@nzeo.com>
* @desc : 페이지 처리
**/
class PageHandler {
var $total_count = 0;
var $total_page = 0;
var $cur_page = 0;
var $page_count = 10;
var $first_page = 1;
var $last_page = 1;
var $point = 0;
function PageHandler($total_count, $total_page, $cur_page, $page_count = 10) {
$this->total_count = $total_count;
$this->total_page = $total_page;
$this->cur_page = $cur_page;
$this->page_count = $page_count;
$this->point = 0;
$first_page = $cur_page-(int)($page_count/2);
if($first_page<1) $first_page = 1;
$last_page = $first_page+$page_count-1;
if($last_page>$total_page) $last_page = $total_page;
$this->first_page = $first_page;
$this->last_page = $last_page;
}
function getNextPage() {
$page = $this->first_page+$this->point++;
if($page > $this->last_page) $page = 0;
return $page;
}
}
?>

View file

@ -0,0 +1,286 @@
<?php
/**
* @file : classes/template/TemplateHandler.class.php
* @author : zero <zero@nzeo.com>
* @desc : 템플릿 컴파일
**/
class TemplateHandler {
var $compiled_path = './files/template_compiled/';
var $tpl_path = '';
var $tpl_file = '';
// public string compile($tpl_path, $tpl_filename)/*{{{*/
function compile($tpl_path, $tpl_filename) {
$this->tpl_path = $tpl_path;
// 디버그를 위한 컴파일 시작 시간 저장
if(__DEBUG__) $start = getMicroTime();
// 변수 체크
if(substr($tpl_path,-1)!='/') $tpl_path .= '/';
if(substr($tpl_filename,-5)!='.html') $tpl_filename .= '.html';
// tpl_file 변수 생성
$tpl_file = $tpl_path.$tpl_filename;
// tpl_file이 비어 있거나 해당 파일이 없으면 return
if(!$tpl_file || !file_exists($tpl_file)) return;
$this->tpl_file = $tpl_file;
// compiled된(or 될) 파일이름을 구함
$compiled_tpl_file = $this->_getCompiledFileName($tpl_file);
// 일단 컴파일
$buff = $this->_compile($tpl_file, $compiled_tpl_file);
if(__DEBUG__) {
$template_elapsed = getMicroTime() - $start;
$GLOBALS['__template_elapsed__'] += $template_elapsed;
}
// Context와 compiled_tpl_file로 컨텐츠 생성
$output = $this->_fetch($compiled_tpl_file, $buff);
// 컴파일된 파일을 실행
return $output;
}/*}}}*/
// private void _compile($tpl_file, $compiled_tpl_file)/*{{{*/
// tpl_file이 컴파일이 되어 있는 것이 있는지 체크
function _compile($tpl_file, $compiled_tpl_file) {
if(!file_exists($compiled_tpl_file)) return $this->_compileTplFile($tpl_file, $compiled_tpl_file);
$source_ftime = filectime($tpl_file);
$target_ftime = filectime($compiled_tpl_file);
if($source_ftime>$target_ftime) return $this->_compileTplFile($tpl_file, $compiled_tpl_file);
}/*}}}*/
// private void _compileTplFile($tpl_file, $compiled_tpl_file)/*{{{*/
// tpl_file을 compile
function _compileTplFile($tpl_file, $compiled_tpl_file) {
// tpl 파일을 읽음
$buff = FileHandler::readFile($tpl_file);
if(!$buff) return;
// 변수를 변경
$buff = preg_replace_callback('/\{[^@^ ]([^\}]+)\}/i', array($this, '_compileVarToContext'), $buff);
// 이미지 태그 img의 src의 값이 ./ 로 시작하면 {$tpl_path}로 변경
$buff = preg_replace_callback('!src=[\'"]{1}(.*?)[\'"]{1}!is', array($this, '_compileImgPath'), $buff);
// 함수를 변경
$buff = preg_replace_callback('/\{\@([^\}]+)\}/i', array($this, '_compileVarToFunc'), $buff);
// <!--@, --> 의 변경
$buff = preg_replace_callback('!<\!--@(.*?)-->!is', array($this, '_compileFuncToCode'), $buff);
// include 변경 <!--#include($path, $filename)-->
$buff = preg_replace_callback('!<\!--#include\(([^\)]*?)\)-->!is', array($this, '_compileIncludeToCode'), $buff);
// import xml filter/ css/ js <!--%filename-->
$buff = preg_replace_callback('!<\!--%import\(\"([^\"]*?)\"\)-->!is', array($this, '_compileImportCode'), $buff);
// 파일에 쓰기 전에 직접 호출되는 것을 방지
$buff = sprintf('%s%s%s','<?php if(!__ZB5__) exit();?>',"\n",$buff);
// 컴파일된 코드를 파일에 저장
FileHandler::writeFile($compiled_tpl_file, $buff);
return $buff;
}/*}}}*/
// private string _compileVarToContext($matches)/*{{{*/
// {$와 } 안의 $... 변수를 Context::get(...) 으로 변경
function _compileVarToContext($matches) {
$str = trim(substr($matches[0],1,strlen($matches[0])-2));
return '<?php print('.preg_replace('/\$([a-zA-Z0-9\_\-\>]+)/i','$__Context->\\1', $str).');?>';
}/*}}}*/
// private string _compileImgPath($matches)/*{{{*/
// {$와 } 안의 $... 변수를 Context::get(...) 으로 변경
function _compileImgPath($matches) {
$str1 = $matches[0];
$str2 = $matches[1];
$path = $str2;
if(!eregi("^\.\/(images|img)",$path)) return $str1;
$path = '<?=$this->tpl_path?>'.substr($path,2);
return str_replace($str2, $path, $str1);
}/*}}}*/
// private string _compileVarToFunc($matches)/*{{{*/
// {@와 } 안의 @... 함수를 print func(..)로 변경
function _compileVarToFunc($matches) {
return '<?php print('.preg_replace('/\$([a-zA-Z0-9\_\-\>]+)/i','$__Context->\\1', trim($matches[1])).');?>';
}/*}}}*/
// private string _compileFuncToCode($matches)/*{{{*/
// <!--@, --> 사이의 구문을 php코드로 변경
function _compileFuncToCode($matches) {
$code = trim($matches[1]);
if(!$code) return;
switch(strtolower($code)) {
case 'else' :
$output = '}else{';
break;
case 'end' :
case 'endif' :
case 'endfor' :
case 'endforeach' :
$output = '}';
break;
default :
if(substr($code,0,4)=='else') {
$code = '}'.$code;
} elseif(substr($code,0,7)=='foreach') {
$tmp_str = substr($code,8);
$tmp_arr = explode(' ', $tmp_str);
$var_name = $tmp_arr[0];
if(substr($var_name,0,1)=='$') $prefix = sprintf('if(is_array($__Context->%s)) ', substr($var_name,1));
else $prefix = sprintf('if(is_array(%s)) ', $var_name);
}
$output = preg_replace('/\$([a-zA-Z0-9\_\-]+)/i','$__Context->\\1', $code).'{';
break;
}
return sprintf('<?php %s %s ?>', $prefix, $output);
}/*}}}*/
// private string _compileIncludeToCode($matches)/*{{{*/
// <!--#include $path-->를 변환
function _compileIncludeToCode($matches) {
// include하려는 대상문자열에 변수가 있으면 변수 처리
$arg = str_replace(array('"','\''), '', $matches[1]);
if(!$arg) return;
$tmp_arr = explode("/", $arg);
for($i=0;$i<count($tmp_arr);$i++) {
$item1 = trim($tmp_arr[$i]);
if($item1=='.'||eregi("\.html$",$item1)) continue;
$tmp2_arr = explode(".",$item1);
for($j=0;$j<count($tmp2_arr);$j++) {
$item = trim($tmp2_arr[$j]);
if(substr($item,0,1)=='$') $item = Context::get(substr($item,1));
$tmp2_arr[$j] = $item;
}
$tmp_arr[$i] = implode(".",$tmp2_arr);
}
$arg = implode("/",$tmp_arr);
if(substr($arg,0,2)=='./') $arg = substr($arg,2);
// 1단계로 해당 tpl 내의 파일을 체크
$filename = sprintf("%s/%s", dirname($this->tpl_file), $arg);
// 2단계로 root로부터 경로를 체크
if(!file_exists($filename)) $filename = './'.$arg;
if(!file_exists($filename)) return;
// path, filename으로 분리
$tmp_arr = explode('/', $filename);
$filename = array_pop($tmp_arr);
$path = implode('/', $tmp_arr).'/';
// include 시도
$output = sprintf(
'<?php%s'.
'$oTemplate = new TemplateHandler();%s'.
'print $oTemplate->compile(\'%s\',\'%s\');%s'.
'?>%s',
"\n",
"\n",
$path,
$filename,
"\n",
"\n"
);
return $output;
}/*}}}*/
// private string _compileImportCode($matches)/*{{{*/
// <!--%filename-->의 확장자를 봐서 js filter/ css/ js 파일을 include하도록 수정
function _compileImportCode($matches) {
// 현재 tpl 파일의 위치를 구해서 $base_path에 저장하여 적용하려는 xml file을 찾음
$base_path = dirname($this->tpl_file).'/';
$given_file = trim($matches[1]);
if(!$given_file) return;
$filename = sprintf("%s%s",$base_path, $given_file);
// path와 파일이름을 구함
$tmp_arr = explode("/",$filename);
$filename = array_pop($tmp_arr);
$base_path = implode("/",$tmp_arr)."/";
// 확장자를 구함
$tmp_arr = explode(".",$filename);
$ext = strtolower(array_pop($tmp_arr));
// 확장자에 따라서 파일 import를 별도로
switch($ext) {
// xml js filter
case 'xml' :
// XmlJSFilter 클래스의 객체 생성후 js파일을 만들고 Context::addJsFile처리
$output = sprintf(
'<?php%s'.
'require_once("./classes/xml/XmlJsFilter.class.php");%s'.
'$oXmlFilter = new XmlJSFilter("%s","%s");%s'.
'$oXmlFilter->compile();%s'.
'?>%s',
"\n",
"\n",
$base_path,
$filename,
"\n",
"\n",
"\n"
);
break;
// css file
case 'css' :
$output = sprintf('<?php Context::addCSSFile("%s%s"); ?>', $base_path, $filename);
break;
// js file
case 'js' :
$output = sprintf('<?php Context::addJsFile("%s%s"); ?>', $base_path, $filename);
break;
}
return $output;
}/*}}}*/
// private string _getComliedFileName($tpl_file) /*{{{*/
// $tpl_file로 compiled_tpl_file이름을 return
function _getCompiledFileName($tpl_file) {
return sprintf('%s%s.compiled.php',$this->compiled_path, md5($tpl_file));
}/*}}}*/
// private string _fetch($compiled_tpl_file)/*{{{*/
// ob_* 함수를 이용하여 fetch...
function _fetch($compiled_tpl_file, $buff = NULL) {
$__Context = &$GLOBALS['__Context__'];
if($_SESSION['is_logged']) $__Context->logged_info->$_SESSION['logged_info'];
// ob_start를 시킨후 컴파일된 tpl파일을 include하고 결과를 return
ob_start();
// tpl파일을 compile하지 못할 경우 $buff로 넘어온 값을 eval시킴 (미설치시에나..)
if($buff) {
$eval_str = "?>".$buff;
eval($eval_str);
} else {
@include $compiled_tpl_file;
}
$output = ob_get_contents();
ob_end_clean();
return $output;
}/*}}}*/
}
?>

View file

@ -0,0 +1,158 @@
<?php
/**
* @file : classes/xml/XmlJSFilter.class.php
* @author : zero <zero@nzeo.com>
* @desc : filter xml문서를 해석하여 js파일로 만듬
* filter xml은 tpl 파일과 같은 위치에 있어야
* <filter id='js function 이름'>
* <field> <-- 항목의 체크
* <item target="name" required="true" minlength="1" maxlength="5"
* filter="email,userid,alpha,number" reualto="target" />
* </field>
* <parameter> <-- 항목을 조합하여 key=val js array로 return, act는 필수
* <item param="key" value="target" concat="'@',target2..." />
* </parameter>
* <response> <-- 서버에 ajax로 전송하여 받을 결과값
* <item name="error" /> <-- error이름의 결과값을 받겠다는
* </response>
* </filter>
*
* - field
* target = element의 이름
* required = true/ false 있어야 하는지에 대한 체크
* minlength, maxlength = 최소/최대 길이
* filter = javascript로 체크하기 위한 체크 필터
* email : email의 형식 ( aaa.aaa@aaa.com)
* userid : 영문+숫자+_, 글자는 영문, 소문자
* alpha : 영문값만 허용
* number : 숫자만 허용
* equalto = target , 현재 폼과 지정 target의 값이 동일해야
* - parameter
* param = key : key를 이름으로 가지고 value의 값을 가지는 array 생성
* value = target : target form element의 값을 가져옴
* concat = str1,str2,target2... : 값들의 string 또는 form element value를 연결
* - response
* name = key : return받을 결과값의 변수명
**/
class XmlJsFilter {
var $compiled_path = './files/js_filter_compiled/';
var $xml_file = NULL;
var $js_file = NULL;
// public void XmlJsFilter($path, $xml_file)/*{{{*/
function XmlJsFilter($path, $xml_file) {
$this->xml_file = sprintf("%s%s",$path, $xml_file);
$this->js_file = $this->_getCompiledFileName($this->xml_file);
}/*}}}*/
// public void compile()/*{{{*/
// 원 xml파일과 compiled된js파일의 시간 비교 및 유무 비교등을 처리
function compile() {
if(!file_exists($this->xml_file)) return;
if(!file_exists($this->js_file)) $this->_compile();
if(filectime($this->xml_file)>filectime($this->js_file)) $this->_compile();
$this->_compile();
Context::addJsFile($this->js_file);
}/*}}}*/
// private void _compile()/*{{{*/
// 실제 xml_file을 컴파일하여 js_file을 생성
function _compile() {
global $lang;
// xml 파일을 읽음
$buff = FileHandler::readFile($this->xml_file);
// xml parsing
$oXml = new XmlParser();
$xml_obj = $oXml->parse($buff);
// XmlJsFilter는 filter_id, field, parameter 3개의 데이터를 핸들링
$filter_id = $xml_obj->filter->attrs->id;
$confirm_msg_code = $xml_obj->filter->attrs->confirm_msg_code;
$field_item = $xml_obj->filter->field->item;
$parameter_item = $xml_obj->filter->parameter->item;
$response_item = $xml_obj->filter->response->item;
// 언어 입력을 위한 사용되는 필드 조사
$target_list = array();
// js function 을 만들기 시작
$js_doc = sprintf("function %s(fo_obj, callback_user_func) {\n", $filter_id);
$js_doc .= "\tvar oFilter = new XmlJsFilter(fo_obj, callback_user_func);\n";
// field, 즉 체크항목의 script 생성
$field_cnt = count($field_item);
if($field_cnt) {
foreach($field_item as $key =>$field_obj) {
$attrs = $field_obj->attrs;
$target = trim($attrs->target);
if(!$target) continue;
$required = $attrs->required=='true'?'true':'false';
$minlength = $attrs->minlength>0?$attrs->minlength:'0';
$maxlength = $attrs->maxlength>0?$attrs->maxlength:'0';
$equalto = trim($attrs->equalto);
$filter = $attrs->filter;
$js_doc .= sprintf(
"\toFilter.addFieldItem(\"%s\",%s,%s,%s,\"%s\",\"%s\");\n",
$target, $required, $minlength, $maxlength, $equalto, $filter
);
if(!in_array($target, $target_list)) $target_list[] = $target;
}
}
// 데이터를 만들기 위한 parameter script 생성
$parameter_cnt = count($parameter_item);
if($parameter_cnt) {
foreach($parameter_item as $key =>$parameter_obj) {
$attrs = $parameter_obj->attrs;
$param = trim($attrs->param);
$target = trim($attrs->target);
if(!$param || !$target) continue;
$target = htmlentities($target,ENT_QUOTES);
$js_doc .= sprintf(
"\toFilter.addParameterItem(\"%s\",\"%s\");\n",
$param, $target
);
if(!in_array($param, $target_list)) $target_list[] = $param;
}
}
// response script 생성
$response_cnt = count($response_item);
for($i=0;$i<$response_cnt;$i++) {
$attrs = $response_item[$i]->attrs;
$name = $attrs->name;
$js_doc .= sprintf("\toFilter.addResponseItem(\"%s\");\n", $name);
}
if($confirm_msg_code) $js_doc .= sprintf("\treturn oFilter.proc(\"%s\");\n",str_replace('"','\"',$lang->{$confirm_msg_code}));
else $js_doc .= sprintf("\treturn oFilter.proc();\n");
$js_doc .= "}\n";
// form 필드 lang 값을 기록
$target_cnt = count($target_list);
for($i=0;$i<$target_cnt;$i++) {
$target = $target_list[$i];
$js_doc .= sprintf("alertMsg[\"%s\"] = \"%s\"\n", $target, str_replace("\"","\\\"",$lang->{$target}));
}
// 에러 메세지를 기록
foreach($lang->filter as $key => $val) {
$js_doc .= sprintf("alertMsg[\"%s\"] = \"%s\";\n", $key, str_replace("\"","\\\"",$val));
}
// js파일 생성
FileHandler::writeFile($this->js_file, $js_doc);
}/*}}}*/
// private string _getCompiledFileName($xml_file) /*{{{*/
// $xml_file로 compiled_xml_file이름을 return
function _getCompiledFileName($xml_file) {
return sprintf('%s%s.%s.compiled.js',$this->compiled_path, md5($xml_file),Context::getLangType());
}/*}}}*/
}
?>

View file

@ -0,0 +1,111 @@
<?php
/**
* @file : classes/xml/XmlParser.class.php
* @author : zero <zero@nzeo.com>
* @desc : xmlrpc를 해석하여 object로 return 하는 simple xml parser
**/
class XmlParser {
var $oParser = NULL;
var $input = NULL;
var $output = array();
var $lang = "en";
// public object loadXmlFile($filename)/*{{{*/
function loadXmlFile($filename) {
if(!file_exists($filename)) return;
$buff = FileHandler::readFile($filename);
$oXmlParser = new XmlParser();
return $oXmlParser->parse($buff);
}/*}}}*/
// public void parse($input)/*{{{*/
function parse($input = '') {
$this->lang = Context::getLangType();
$this->input = $input?$input:$GLOBALS['HTTP_RAW_POST_DATA'];
// 지원언어 종류를 뽑음
preg_match_all("/xml:lang=\"([^\"].+)\"/i", $this->input, $matches);
// xml:lang이 쓰였을 경우 지원하는 언어종류를 뽑음
if(count($matches[1]) && $supported_lang = array_unique($matches[1])) {
// supported_lang에 현재 접속자의 lang이 없으면 en이 있는지 확인하여 en이 있으면 en을 기본, 아니면 첫번째것을..
if(!in_array($this->lang, $supported_lang)) {
if(in_array('en', $supported_lang)) {
$this->lang = 'en';
} else {
$this->lang = array_shift($supported_lang);
}
}
// 특별한 언어가 지정되지 않았다면 언어체크를 하지 않음
} else {
unset($this->lang);
}
$this->oParser = xml_parser_create();
xml_set_object($this->oParser, $this);
xml_set_element_handler($this->oParser, "_tagOpen", "_tagClosed");
xml_set_character_data_handler($this->oParser, "_tagBody");
xml_parse($this->oParser, $this->input);
xml_parser_free($this->oParser);
if(!count($this->output)) return;
return array_shift($this->output);
}/*}}}*/
// private void _tagOpen($parser, $node_name, $attrs)/*{{{*/
function _tagOpen($parser, $node_name, $attrs) {
$obj->node_name = strtolower($node_name);
$obj->attrs = $this->_arrToObj($attrs);
array_push($this->output, $obj);
}/*}}}*/
// private void _tagBody($parser, $body)/*{{{*/
function _tagBody($parser, $body) {
if(!trim($body)) return;
$this->output[count($this->output)-1]->body .= $body;
}/*}}}*/
// private void _tagClosed($parser, $node_name)/*{{{*/
function _tagClosed($parser, $node_name) {
$node_name = strtolower($node_name);
$cur_obj = array_pop($this->output);
$parent_obj = &$this->output[count($this->output)-1];
if($this->lang&&$cur_obj->attrs->{'xml:lang'}&&$cur_obj->attrs->{'xml:lang'}!=$this->lang) return;
if($this->lang&&$parent_obj->{$node_name}->attrs->{'xml:lang'}&&$parent_obj->{$node_name}->attrs->{'xml:lang'}!=$this->lang) return;
if($parent_obj->{$node_name}) {
$tmp_obj = $parent_obj->{$node_name};
if(is_array($tmp_obj)) {
array_push($parent_obj->{$node_name}, $cur_obj);
} else {
$parent_obj->{$node_name} = array();
array_push($parent_obj->{$node_name}, $tmp_obj);
array_push($parent_obj->{$node_name}, $cur_obj);
}
} else {
$parent_obj->{$node_name} = $cur_obj;
}
}/*}}}*/
// private void _arrToObj($arr)/*{{{*/
function _arrToObj($arr) {
if(!count($arr)) return;
foreach($arr as $key => $val) {
$key = strtolower($key);
$output->{$key} = $val;
}
return $output;
}/*}}}*/
}
?>

View file

@ -0,0 +1,340 @@
<?php
/**
* @file : classes/db/DB.class.php
* @author : zero <zero@nzeo.com>
* @desc : query xml을 파싱하여 결과를 return
**/
class XmlQueryParser {
// 조건문에서 조건을 등호로 표시하는 변수
var $cond_operation = array(
'equal' => '=',
'more' => '>=',
'excess' => '>',
'less' => '<=',
'below' => '<',
'notequal' => '!=',
'notnull' => 'is not null',
'null' => 'is null',
);
// private string parse($query_id, $xml_file, $cache_file)/*{{{*/
// 쿼리 파일을 찾아서 파싱하고 cacheing한다
function parse($query_id, $xml_file, $cache_file) {
// query xml 파일을 찾아서 파싱, 결과가 없으면 return
$buff = FileHandler::readFile($xml_file);
$oXml = new XmlParser();
$xml_obj = $oXml->parse($buff);
if(!$xml_obj) return;
// 쿼리 스크립트를 만들때 필요한 변수들
$filter_script = $notnull_script = $column_script = $default_script = '';
// insert, update, delete, select등의 action
$action = strtolower($xml_obj->query->attrs->action);
if(!$action) return;
// 테이블 정리 (배열코드로 변환)
$tables = $this->_getTablesScript($xml_obj);
// 컬럼 정리
$column_script = $this->_getColumnsScript($xml_obj, $default_script, $notnull_script, $filter_script, $action);
// 조건절 정리
$condition_script = $this->_getConditionScript($xml_obj, $default_script, $notnull_script, $filter_script);
// group 정리
$group_script = $this->_getGroupScript($xml_obj);
// 네비게이션 정리
$navigation_script = $this->_getNavigationScript($xml_obj);
// 캐쉬 내용 작성
$buff =
sprintf(
'<?php if(!__ZB5__) exit();'."\n".
'$pass_quotes = array();'."\n".
'$id = \'%s\';'."\n".
'$action = \'%s\';'."\n".
'$tables = array(%s);'."\n".
'%s'."\n".
'%s'."\n".
'%s'."\n".
'%s'."\n".
'%s'."\n".
'%s'."\n".
'$group_script = \'%s\''."\n".
'?>',
$query_id,
$action,
$tables,
$default_script,
$column_script,
$notnull_script,
$filter_script,
$condition_script,
$navigation_script,
$group_script
);
// 저장
FileHandler::writeFile($cache_file, $buff);
}/*}}}*/
// private string _getDefaultCode($name, $value)/*{{{*/
function _getDefaultCode($name, $value) {
if(!$value) return;
if(substr($value, -1)!=')') return sprintf('if(!$args->%s) $args->%s = \'%s\';'."\n", $name, $name, $value);
$str_pos = strpos($value, '(');
$func_name = substr($value, 0, $str_pos);
$args = substr($value, $str_pos+1, strlen($value)-1);
switch($func_name) {
case 'ipaddress' :
$val = '\''.$_SERVER['REMOTE_ADDR'].'\'';
break;
case 'unixtime' :
$val = 'time()';
break;
case 'curdate' :
$val = 'date("YmdHis")';
break;
case 'sequence' :
$val = '$this->getNextSequence()';
break;
case 'plus' :
$args = abs($args);
$val = sprintf('\'%s+%d\'', $name, $args);
$pass_quotes = true;
break;
case 'minus' :
$args = abs($args);
$val = sprintf('\'%s-%d\'', $name, $args);
$pass_quotes = true;
break;
}
$output = sprintf('if(!$args->%s) $args->%s = %s;'."\n", $name, $name, $val);
if($pass_quotes) $output .= sprintf('$pass_quotes[] = \'%s\';'."\n",$name);
return $output;
}/*}}}*/
// private string _getFilterCode($key, $type, $minlength, $maxlength, $var='column')/*{{{*/
function _getFilterCode($key, $type, $minlength, $maxlength, $var='column', $notnull='') {
if(!$type||!$minlength||!$maxlength) return;
if(!$notnull) $notnull_code = sprintf('if($%s->%s) ', $var, $key);
return
sprintf('unset($output); %s$output = $this->_checkFilter(\'%s\', $%s->%s, \'%s\', \'%d\', \'%d\'); if(!$output->toBool()) return $output;'."\n",
$notnull_code,
$key,
$var,
$key,
$type,
(int)$minlength,
(int)$maxlength
);
}/*}}}*/
// private string _getNotNullCode($name)/*{{{*/
function _getNotNullCode($name, $var='column') {
return
sprintf('if(!$%s->%s) return new Output(-1, sprintf($lang->filter->isnull, $lang->%s?$lang->%s:\'%s\'));'."\n",
$var,
$name,
$name,
$name,
$name
);
}/*}}}*/
// private string _getTablesScript($xml_obj) /*{{{*/
function _getTablesScript($xml_obj) {
$obj_tables = $xml_obj->query->tables->table;
if(!is_array($obj_tables)) $obj_tables = array('', $obj_tables);
foreach($obj_tables as $table_info) {
$name = trim($table_info->attrs->name);
if(!$name) continue;
$alias = trim($table_info->attrs->alias);
if(!$alias) $alias = $name;
$table_list[] = sprintf('\'%s\'=>\'%s\'', $name, $alias);
}
return implode(",",$table_list);
}/*}}}*/
// private string _getColumnsScript($xml_obj, &$default_script, &$notnull_script, &$filter_script, $action)/*{{{*/
function _getColumnsScript($xml_obj, &$default_script, &$notnull_script, &$filter_script, $action) {
$obj_columns = $xml_obj->query->columns->column;
if(!is_array($obj_columns)) $obj_columns = array('', $obj_columns);
foreach($obj_columns as $column_info) {
$name = trim($column_info->attrs->name);
if(!$name || $name == '*') continue;
$var = trim($column_info->attrs->var);
$alias = trim($column_info->attrs->alias);
if(!$alias) $alias = $name;
$default = trim($column_info->attrs->default);
$notnull = trim($column_info->attrs->notnull);
$filter_type = trim($column_info->attrs->filter);
$minlength = (int)trim($column_info->attrs->minlength);
$maxlength = (int)trim($column_info->attrs->maxlength);
$column_script .= sprintf('$column->%s = $args->%s;'."\n", $alias, $var?$var:$alias);
$invert_columns[] = sprintf('\'%s\'=>\'%s\'', $alias, $name);
$default_script .= $this->_getDefaultCode($alias, $default);
if($action != 'select') {
if($filter_type) $filter_script .= $this->_getFilterCode($alias, $filter_type, $minlength, $maxlength, 'column', $notnull);
if($notnull) $notnull_script .= $this->_getNotNullCode($alias);
}
}
if(is_array($invert_columns)) $column_script .= sprintf('$invert_columns = array(%s);'."\n", implode(',',$invert_columns));
return $column_script;
}/*}}}*/
// private string _getConditionScript($xml_obj, &$default_script, &$notnull_script, &$filter_script)/*{{{*/
function _getConditionScript($xml_obj, &$default_script, &$notnull_script, &$filter_script) {
$cond_idx = 0;
$obj_conditions = $xml_obj->query->conditions->condition;
$condition_script = $condition = $this->_getConditionQuery($cond_idx++, $obj_conditions, NULL, $notnull_script, $filter_script);
$obj_groups = $xml_obj->query->conditions->group;
if(!is_array($obj_groups)) $obj_groups = array('', $obj_groups);
foreach($obj_groups as $obj_group) {
$group_pipe = $obj_group->attrs->pipe;
if(!$group_pipe) continue;
$buff = $this->_getConditionQuery($cond_idx++, $obj_group->condition, $group_pipe, $notnull_script, $filter_script);
$condition_script .= $buff;
}
$condition_script .= '$condition = $this->_combineCondition($cond_group, $group_pipe);'."\n";
return $condition_script;
}/*}}}*/
// private string _getConditionQuery($cond_idx, $obj, $group_pipe, &$notnull_script, &$filter_script) /*{{{*/
// 조건문의 쿼리를 만들어 줌
function _getConditionQuery($cond_idx, $obj, $group_pipe, &$notnull_script, &$filter_script) {
if(!is_array($obj)) $obj = array('', $obj);
$idx = 0;
foreach($obj as $obj_cond) {
$operation = $obj_cond->attrs->operation;
if(!$operation) continue;
$column = $obj_cond->attrs->column;
$var = $obj_cond->attrs->var;
$filter = $obj_cond->attrs->filter;
$notnull = $obj_cond->attrs->notnull;
$pipe = $obj_cond->attrs->pipe;
if(!$pipe) $pipe = 'and';
$default = $obj_cond->attrs->default;
// 비교 대상이 다른 혹은 같은 테이블의 column일 경우
if(eregi("\.", $var)) {
switch($operation) {
case 'in' :
$buff = sprintf('%s in (%s)', $column, $var);
break;
default :
$operation = $this->cond_operation[$operation];
if(!$operation) $operation = 'and';
$buff = sprintf('%s %s %s', $column, $operation, $var);
break;
}
$condition_script .= sprintf('$cond_group[%d][][\'%s\'] = \'%s\';'."\n",$cond_idx, $pipe, $buff);
// 입력받을 변수일 경우
} else {
switch($operation) {
case 'like' :
$buff = sprintf('sprintf("%s like \'%%%%%%s%%%%\' ", $this->addQuotes($args->%s))', $column, $var);
break;
case 'like_prefix' :
$buff = sprintf('sprintf("%s like \'%%s%%%%\' ", $this->addQuotes($args->%s))', $column, $var);
break;
case 'in' :
$buff = sprintf('sprintf("%s in (%%s) ", $this->addQuotes($args->%s))', $column, $var);
break;
case 'notnull' :
case 'null' :
$operation = $this->cond_operation[$operation];
unset($var);
$buff = sprintf('"%s %s "', $column, $operation);
break;
default :
$operation = $this->cond_operation[$operation];
if($default) $buff = sprintf('sprintf("%s %s \'%%s\' ", $args->%s?$this->addQuotes($args->%s):\'%s\')', $column, $operation, $var?$var:$column, $var?$var:$column, $default);
else $buff = sprintf('sprintf("%s %s \'%%s\' ", $this->addQuotes($args->%s))', $column, $operation, $var?$var:$column);
break;
}
$buff = sprintf('$cond_group[%d][][\'%s\'] = %s;'."\n",$cond_idx, $pipe, $buff);
if(!$notnull && $var) $buff = sprintf('if($args->%s) ', $var).$buff;
$condition_script .= $buff;
if($notnull) $notnull_script .= $this->_getNotNullCode($var?$var:$column, 'args');
if($filter) $filter_script .= $this->_getFilterCode($var, $filter, 0, 0, 'args', $notnull);
}
}
$condition_script .= sprintf('$group_pipe[%d] = \'%s\';'."\n", $cond_idx, $group_pipe);
return $condition_script;
}/*}}}*/
// private string _getGroupScript($xml_obj)/*{{{*/
function _getGroupScript($xml_obj) {
$group_list = $xml_obj->query->groups->group;
if(!$group_list) return;
if(!is_array($group_list)) $group_list = array($group_list);
for($i=0;$i<count($group_list);$i++) {
$group = $group_list[$i];
$column = trim($group->attrs->column);
if(!$column) continue;
$group_column_list[] = $column;
}
if(count($group_column_list)) {
return ' group by '.implode(" , ", $group_column_list);
}
}/*}}}*/
// private string _getNavigationScript($xml_obj) /*{{{*/
function _getNavigationScript($xml_obj) {
$obj_navigation = $xml_obj->query->navigation;
if(!$obj_navigation) return;
$obj_index = $obj_navigation->index->attrs;
$index_list = array();
if(!is_array($obj_index)) $obj_index = array('', $obj_index);
foreach($obj_index as $index_info) {
$var = trim($index_info->var);
if(!$var) continue;
$default = trim($index_info->default);
$order = trim($index_info->order);
if(!$order) $order = 'asc';
$navigation_script .= sprintf('$navigation->index[] = array($args->%s?$args->%s:\'%s\', \'%s\');'."\n", $var, $var, $default, $order);
}
$obj_list_count = $obj_navigation->list_count->attrs;
$count_var = $obj_list_count->var;
$count_default = $obj_list_count->default;
if($count_var) $navigation_script .= sprintf('$navigation->list_count = $args->%s?$args->%s%s;'."\n", $count_var, $count_var, $count_default?':'.$count_default:'');
$obj_page_count = $obj_navigation->page_count->attrs;
$count_var = $obj_page_count->var;
$count_default = $obj_page_count->default;
if($count_var) $navigation_script .= sprintf('$navigation->page_count = $args->%s?$args->%s%s;'."\n", $count_var, $count_var, $count_default?':'.$count_default:'');
$obj_page = $obj_navigation->page->attrs;
$page_var = $obj_page->var;
$page_default = $obj_page->default;
if($page_var) $navigation_script .= sprintf('$navigation->page = $args->%s?$args->%s%s;'."\n", $page_var, $page_var, $page_default?':'.$page_default:'');
return $navigation_script;
}/*}}}*/
}
?>

42
common/css/default.css Normal file
View file

@ -0,0 +1,42 @@
#waitingforserverresponse {
display:inline;
border:2px solid #444444;
background-color:#FFFFFF;
padding:15px 20px 13px 20px;
font-weight:bold;
font-size:9pt;
color:#444444;
top:40px;
left:40px;
position:absolute;
z-index:100;
visibility:hidden;
}
A.bold {
font-weight:bold;
}
A.editor_blue_text:link { color: #17B1B7; text-decoration:none; border-bottom:2px solid #17B1B7;}
A.editor_blue_text:visited { color: #17B1B7; text-decoration:none; border-bottom:2px solid #17B1B7;}
A.editor_blue_text:active { color: #17B1B7; text-decoration:none; border-bottom:2px solid #17B1B7;}
A.editor_blue_text:hover { color: #17B1B7; text-decoration:none; border-bottom:2px solid #17B1B7;}
A.editor_red_text:link { color: #B71717; text-decoration:none; border-bottom:2px solid #B71717; }
A.editor_red_text:visited { color: #B71717; text-decoration:none; border-bottom:2px solid #B71717;}
A.editor_red_text:active { color: #B71717; text-decoration:none; border-bottom:2px solid #B71717;}
A.editor_red_text:hover { color: #B71717; text-decoration:none; border-bottom:2px solid #B71717;}
A.editor_yellow_text:link { color: #6A8308; text-decoration:none; border-bottom:2px solid #6A8308; }
A.editor_yellow_text:visited { color: #6A8308; text-decoration:none; border-bottom:2px solid #6A8308;}
A.editor_yellow_text:active { color: #6A8308; text-decoration:none; border-bottom:2px solid #6A8308;}
A.editor_yellow_text:hover { color: #6A8308; text-decoration:none; border-bottom:2px solid #6A8308;}
A.editor_green_text:link { color: #08830B; text-decoration:none; border-bottom:2px solid #08830B;}
A.editor_green_text:visited { color: #08830B; text-decoration:none; border-bottom:2px solid #08830B;}
A.editor_green_text:active { color: #08830B; text-decoration:none; border-bottom:2px solid #08830B;}
A.editor_green_text:hover { color: #08830B; text-decoration:none; border-bottom:2px solid #08830B;}
.folder_opener { display: block; }
.folder_closer { display: none; }
.folder_area { display: none; }

122
common/js/common.js Normal file
View file

@ -0,0 +1,122 @@
/**
* 몇가지 유용한 & 기본적으로 자주 사용되는 자바스크립트 함수들 모음
**/
// string prototype으로 trim 함수 추가
String.prototype.trim = function() {/*{{{*/
return this.replace(/(^\s*)|(\s*$)/g, "");
}/*}}}*/
// 주어진 인자가 하나라도 defined되어 있지 않으면 false return
function isDef() {/*{{{*/
for(var i=0; i<arguments.length; ++i) {
if(typeof(arguments[i])=='undefined') return false;
}
return true;
}/*}}}*/
// 특정 div(or span...)의 display옵션 토글
function toggleDisplay(obj, opt) {/*{{{*/
obj = xGetElementById(obj);
if(typeof(opt)=='undefined') opt = 'inline';
if(obj.style.display == 'none') obj.style.display = opt;
else obj.style.display = 'none';
}/*}}}*/
// 멀티미디어 출력용 (IE에서 플래쉬/동영상 주변에 점선 생김 방지용)
function displayMultimedia(type, src, style) {/*{{{*/
var clsid = '';
var codebase = '';
var html = '';
switch(type) {
case 'flv' :
case 'swf' :
clsid = 'clsid:D27CDB6E-AE6D-11cf-96B8-444553540000';
codebase = 'http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.c-ab#version=6,0,29,0';
html = ""+
"<script type=\"text/javascript\">"+
"document.writeln(\""+
"<object classid='"+clsid+"' codebase='"+codebase+"' "+style+">"+
"<param name='movie' value='"+src+"' />"+
"<param name='quality' value='high' />"+
"<embed src='"+src+"' autostart='0' "+style+"></embed>"+
"<\/object>"+
"\");"+
"</script>";
break;
default :
html = ""+
"<script type=\"text/javascript\">"+
"document.writeln(\""+
"<embed src='"+src+"' autostart='0' "+style+"></embed>"+
"\");"+
"</script>";
break;
}
return html;
}/*}}}*/
// 화면내에서 이미지 리사이즈 및 클릭할 수 있도록
function resizeImageContents() {/*{{{*/
var objs = xGetElementsByTagName('img');
for(var i in objs) {
var obj = objs[i];
var parent = xParent(obj);
if(!obj||!parent) continue;
var parent_width = xWidth(parent);
var obj_width = xWidth(obj);
if(parent_width>=obj_width) continue;
obj.style.cursor = 'pointer';
obj.source_width = obj_width;
obj.source_height = xHeight(obj);
xWidth(obj, xWidth(parent)-1);
xAddEventListener(obj,'click', resizeImagePopup);
}
}/*}}}*/
xAddEventListener(window, 'load', resizeImageContents);
function resizeImagePopup(evt) {/*{{{*/
var e = new xEvent(evt);
if(!e.target.src) return;
var obj = e.target;
var scrollbars = "no";
var resizable = "no";
var width = obj.source_width;
if(width>screen.availWidth) {
width = screen.availWidth-50;
scrollbars = "yes";
resizable = "yes";
}
var height = obj.source_height;
if(height>screen.availHeight) {
height = screen.availHeight-50;
scrollbars = "yes";
resizable = "yes";
}
var popup = window.open(e.target.src,"_imagePopup","width="+width+",height="+height+",top=1,left=1,resizable="+resizable+",toolbars=no,scrollbars="+resizable);
if(popup) popup.focus();
}/*}}}*/
// 에디터에서 사용하는 내용 여닫는 코드 (고정)
function svc_folder_open(id) {/*{{{*/
var open_text_obj = xGetElementById("_folder_open_"+id);
var close_text_obj = xGetElementById("_folder_close_"+id);
var folder_obj = xGetElementById("_folder_"+id);
open_text_obj.style.display = "none";
close_text_obj.style.display = "block";
folder_obj.style.display = "block";
}/*}}}*/
function svc_folder_close(id) {/*{{{*/
var open_text_obj = xGetElementById("_folder_open_"+id);
var close_text_obj = xGetElementById("_folder_close_"+id);
var folder_obj = xGetElementById("_folder_"+id);
open_text_obj.style.display = "block";
close_text_obj.style.display = "none";
folder_obj.style.display = "none";
}/*}}}*/

633
common/js/x.js Normal file
View file

@ -0,0 +1,633 @@
/* x.js compiled from X 4.0 with XC 0.27b.
* Distributed by GNU LGPL. For copyrights, license, documentation and more visit Cross-Browser.com
* Copyright 2001-2005 Michael Foster (Cross-Browser.com)
*/
var xOp7Up,xOp6Dn,xIE4Up,xIE4,xIE5,xIE6,xNN4,xUA=navigator.userAgent.toLowerCase();
if(window.opera){
var i=xUA.indexOf('opera');
if(i!=-1){
var v=parseInt(xUA.charAt(i+6));
xOp7Up=v>=7;
xOp6Dn=v<7;
}
}
else if(navigator.vendor!='KDE' && document.all && xUA.indexOf('msie')!=-1){
xIE4Up=parseFloat(navigator.appVersion)>=4;
xIE4=xUA.indexOf('msie 4')!=-1;
xIE5=xUA.indexOf('msie 5')!=-1;
xIE6=xUA.indexOf('msie 6')!=-1;
}
else if(document.layers){xNN4=true;}
xMac=xUA.indexOf('mac')!=-1;
// (element, event(without 'on'), event listener(function name)[, caption])
function xAddEventListener(e,eT,eL,cap)
{
if(!(e=xGetElementById(e))) return;
eT=eT.toLowerCase();
if((!xIE4Up && !xOp7Up) && e==window) {
if(eT=='resize') { window.xPCW=xClientWidth(); window.xPCH=xClientHeight(); window.xREL=eL; xResizeEvent(); return; }
if(eT=='scroll') { window.xPSL=xScrollLeft(); window.xPST=xScrollTop(); window.xSEL=eL; xScrollEvent(); return; }
}
var eh='e.on'+eT+'=eL';
if(e.addEventListener) e.addEventListener(eT,eL,cap);
else if(e.attachEvent) e.attachEvent('on'+eT,eL);
else eval(eh);
}
// called only from the above
function xResizeEvent()
{
if (window.xREL) setTimeout('xResizeEvent()', 250);
var cw = xClientWidth(), ch = xClientHeight();
if (window.xPCW != cw || window.xPCH != ch) { window.xPCW = cw; window.xPCH = ch; if (window.xREL) window.xREL(); }
}
function xScrollEvent()
{
if (window.xSEL) setTimeout('xScrollEvent()', 250);
var sl = xScrollLeft(), st = xScrollTop();
if (window.xPSL != sl || window.xPST != st) { window.xPSL = sl; window.xPST = st; if (window.xSEL) window.xSEL(); }
}
function xAppendChild(oParent, oChild)
{
if (oParent.appendChild) return oParent.appendChild(oChild);
else return null;
}
function xClientHeight()
{
var h=0;
if(xOp6Dn) h=window.innerHeight;
else if(document.compatMode == 'CSS1Compat' && !window.opera && document.documentElement && document.documentElement.clientHeight)
h=document.documentElement.clientHeight;
else if(document.body && document.body.clientHeight)
h=document.body.clientHeight;
else if(xDef(window.innerWidth,window.innerHeight,document.width)) {
h=window.innerHeight;
if(document.width>window.innerWidth) h-=16;
}
return h;
}
function xClientWidth()
{
var w=0;
if(xOp6Dn) w=window.innerWidth;
else if(document.compatMode == 'CSS1Compat' && !window.opera && document.documentElement && document.documentElement.clientWidth)
w=document.documentElement.clientWidth;
else if(document.body && document.body.clientWidth)
w=document.body.clientWidth;
else if(xDef(window.innerWidth,window.innerHeight,document.height)) {
w=window.innerWidth;
if(document.height>window.innerHeight) w-=16;
}
return w;
}
function xCreateElement(sTag)
{
if (document.createElement) return document.createElement(sTag);
else return null;
}
function xDef()
{
for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])=='undefined') return false;}
return true;
}
function xDeleteCookie(name, path)
{
if (xGetCookie(name)) {
document.cookie = name + "=" +
"; path=" + ((!path) ? "/" : path) +
"; expires=" + new Date(0).toGMTString();
}
}
function xDisplay(e,s)
{
if(!(e=xGetElementById(e))) return null;
if(e.style && xDef(e.style.display)) {
if (xStr(s)) e.style.display = s;
return e.style.display;
}
return null;
}
function xEvent(evt) // object prototype
{
var e = evt || window.event;
if(!e) return;
if(e.type) this.type = e.type;
if(e.target) this.target = e.target;
else if(e.srcElement) this.target = e.srcElement;
// Section B
if (e.relatedTarget) this.relatedTarget = e.relatedTarget;
else if (e.type == 'mouseover' && e.fromElement) this.relatedTarget = e.fromElement;
else if (e.type == 'mouseout') this.relatedTarget = e.toElement;
// End Section B
if(xOp6Dn) { this.pageX = e.clientX; this.pageY = e.clientY; }
else if(xDef(e.pageX,e.pageY)) { this.pageX = e.pageX; this.pageY = e.pageY; }
else if(xDef(e.clientX,e.clientY)) { this.pageX = e.clientX + xScrollLeft(); this.pageY = e.clientY + xScrollTop(); }
// Section A
if (xDef(e.offsetX,e.offsetY)) {
this.offsetX = e.offsetX;
this.offsetY = e.offsetY;
}
else if (xDef(e.layerX,e.layerY)) {
this.offsetX = e.layerX;
this.offsetY = e.layerY;
}
else {
this.offsetX = this.pageX - xPageX(this.target);
this.offsetY = this.pageY - xPageY(this.target);
}
// End Section A
if (e.keyCode) { this.keyCode = e.keyCode; } // for moz/fb, if keyCode==0 use which
else if (xDef(e.which) && e.type.indexOf('key')!=-1) { this.keyCode = e.which; }
this.shiftKey = e.shiftKey;
this.ctrlKey = e.ctrlKey;
this.altKey = e.altKey;
}
function xFirstChild(e, t)
{
var c = e ? e.firstChild : null;
if (t) while (c && c.nodeName != t) { c = c.nextSibling; }
else while (c && c.nodeType != 1) { c = c.nextSibling; }
return c;
}
function xGetBodyWidth() {
var cw = xClientWidth();
var sw = window.document.body.scrollWidth;
return cw>sw?cw:sw;
}
function xGetBodyHeight() {
var cw = xClientHeight();
var sw = window.document.body.scrollHeight;
return cw>sw?cw:sw;
}
function xGetComputedStyle(oEle, sProp, bInt)
{
var s, p = 'undefined';
var dv = document.defaultView;
if(dv && dv.getComputedStyle){
s = dv.getComputedStyle(oEle,'');
if (s) p = s.getPropertyValue(sProp);
}
else if(oEle.currentStyle) {
// convert css property name to object property name for IE
var a = sProp.split('-');
sProp = a[0];
for (var i=1; i<a.length; ++i) {
c = a[i].charAt(0);
sProp += a[i].replace(c, c.toUpperCase());
}
p = oEle.currentStyle[sProp];
}
else return null;
return bInt ? (parseInt(p) || 0) : p;
}
function xGetCookie(name)
{
var value=null, search=name+"=";
if (document.cookie.length > 0) {
var offset = document.cookie.indexOf(search);
if (offset != -1) {
offset += search.length;
var end = document.cookie.indexOf(";", offset);
if (end == -1) end = document.cookie.length;
value = unescape(document.cookie.substring(offset, end));
}
}
return value;
}
function xGetElementById(e)
{
if(typeof(e)!='string') return e;
if(document.getElementById) e=document.getElementById(e);
else if(document.all) e=document.all[e];
else e=null;
return e;
}
function xGetElementsByAttribute(sTag, sAtt, sRE, fn)
{
var a, list, found = new Array(), re = new RegExp(sRE, 'i');
list = xGetElementsByTagName(sTag);
for (var i = 0; i < list.length; ++i) {
a = list[i].getAttribute(sAtt);
if (!a) {a = list[i][sAtt];}
if (typeof(a)=='string' && a.search(re) != -1) {
found[found.length] = list[i];
if (fn) fn(list[i]);
}
}
return found;
}
function xGetElementsByClassName(c,p,t,f)
{
var found = new Array();
var re = new RegExp('\\b'+c+'\\b', 'i');
var list = xGetElementsByTagName(t, p);
for (var i = 0; i < list.length; ++i) {
if (list[i].className && list[i].className.search(re) != -1) {
found[found.length] = list[i];
if (f) f(list[i]);
}
}
return found;
}
function xGetElementsByTagName(t,p)
{
var list = null;
t = t || '*';
p = p || document;
if (xIE4 || xIE5) {
if (t == '*') list = p.all;
else list = p.all.tags(t);
}
else if (p.getElementsByTagName) list = p.getElementsByTagName(t);
return list || new Array();
}
function xGetURLArguments()
{
var idx = location.href.indexOf('?');
var params = new Array();
if (idx != -1) {
var pairs = location.href.substring(idx+1, location.href.length).split('&');
for (var i=0; i<pairs.length; i++) {
nameVal = pairs[i].split('=');
params[i] = nameVal[1];
params[nameVal[0]] = nameVal[1];
}
}
return params;
}
function xHeight(e,h)
{
if(!(e=xGetElementById(e))) return 0;
if (xNum(h)) {
if (h<0) h = 0;
else h=Math.round(h);
}
else h=-1;
var css=xDef(e.style);
if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
h = xClientHeight();
}
else if(css && xDef(e.offsetHeight) && xStr(e.style.height)) {
if(h>=0) {
var pt=0,pb=0,bt=0,bb=0;
if (document.compatMode=='CSS1Compat') {
var gcs = xGetComputedStyle;
pt=gcs(e,'padding-top',1);
if (pt !== null) {
pb=gcs(e,'padding-bottom',1);
bt=gcs(e,'border-top-width',1);
bb=gcs(e,'border-bottom-width',1);
}
// Should we try this as a last resort?
// At this point getComputedStyle and currentStyle do not exist.
else if(xDef(e.offsetHeight,e.style.height)){
e.style.height=h+'px';
pt=e.offsetHeight-h;
}
}
h-=(pt+pb+bt+bb);
if(isNaN(h)||h<0) return;
else e.style.height=h+'px';
}
h=e.offsetHeight;
}
else if(css && xDef(e.style.pixelHeight)) {
if(h>=0) e.style.pixelHeight=h;
h=e.style.pixelHeight;
}
return h;
}
function xHex(n, digits, prefix)
{
var p = '', n = Math.ceil(n);
if (prefix) p = prefix;
n = n.toString(16);
for (var i=0; i < digits - n.length; ++i) {
p += '0';
}
return p + n;
}
function xHide(e){return xVisibility(e,0);}
function xInnerHtml(e,h)
{
if(!(e=xGetElementById(e)) || !xStr(e.innerHTML)) return null;
var s = e.innerHTML;
if (xStr(h)) {e.innerHTML = h;}
return s;
}
function xLeft(e, iX)
{
if(!(e=xGetElementById(e))) return 0;
var css=xDef(e.style);
if (css && xStr(e.style.left)) {
if(xNum(iX)) e.style.left=iX+'px';
else {
iX=parseInt(e.style.left);
if(isNaN(iX)) iX=0;
}
}
else if(css && xDef(e.style.pixelLeft)) {
if(xNum(iX)) e.style.pixelLeft=iX;
else iX=e.style.pixelLeft;
}
return iX;
}
function xMoveTo(e,x,y)
{
xLeft(e,x);
xTop(e,y);
}
function xName(e)
{
if (!e) return e;
else if (e.id && e.id != "") return e.id;
else if (e.name && e.name != "") return e.name;
else if (e.nodeName && e.nodeName != "") return e.nodeName;
else if (e.tagName && e.tagName != "") return e.tagName;
else return e;
}
function xNextSib(e,t)
{
var s = e ? e.nextSibling : null;
if (t) while (s && s.nodeName != t) { s = s.nextSibling; }
else while (s && s.nodeType != 1) { s = s.nextSibling; }
return s;
}
function xNum()
{
for(var i=0; i<arguments.length; ++i){if(isNaN(arguments[i]) || typeof(arguments[i])!='number') return false;}
return true;
}
function xOffsetLeft(e)
{
if (!(e=xGetElementById(e))) return 0;
if (xDef(e.offsetLeft)) return e.offsetLeft;
else return 0;
}
function xOffsetTop(e)
{
if (!(e=xGetElementById(e))) return 0;
if (xDef(e.offsetTop)) return e.offsetTop;
else return 0;
}
function xPad(s,len,c,left)
{
if(typeof s != 'string') s=s+'';
if(left) {for(var i=s.length; i<len; ++i) s=c+s;}
else {for (i=s.length; i<len; ++i) s+=c;}
return s;
}
function xPageX(e)
{
if (!(e=xGetElementById(e))) return 0;
var x = 0;
while (e) {
if (xDef(e.offsetLeft)) x += e.offsetLeft;
e = xDef(e.offsetParent) ? e.offsetParent : null;
}
return x;
}
function xPageY(e)
{
if (!(e=xGetElementById(e))) return 0;
var y = 0;
while (e) {
if (xDef(e.offsetTop)) y += e.offsetTop;
e = xDef(e.offsetParent) ? e.offsetParent : null;
}
// if (xOp7Up) return y - document.body.offsetTop; // v3.14, temporary hack for opera bug 130324 (reported 1nov03)
return y;
}
function xParent(e, bNode)
{
if (!(e=xGetElementById(e))) return null;
var p=null;
if (!bNode && xDef(e.offsetParent)) p=e.offsetParent;
else if (xDef(e.parentNode)) p=e.parentNode;
else if (xDef(e.parentElement)) p=e.parentElement;
return p;
}
function xParentChain(e,delim,bNode)
{
if (!(e=xGetElementById(e))) return;
var lim=100, s = "", d = delim || "\n";
while(e) {
s += xName(e) + ', ofsL:'+e.offsetLeft + ', ofsT:'+e.offsetTop + d;
e = xParent(e,bNode);
if (!lim--) break;
}
return s;
}
function xPreventDefault(e)
{
if (e && e.preventDefault) e.preventDefault()
else if (window.event) window.event.returnValue = false;
}
function xPrevSib(e,t)
{
var s = e ? e.previousSibling : null;
if (t) while(s && s.nodeName != t) {s=s.previousSibling;}
else while(s && s.nodeType != 1) {s=s.previousSibling;}
return s;
}
function xRemoveEventListener(e,eT,eL,cap)
{
if(!(e=xGetElementById(e))) return;
eT=eT.toLowerCase();
if((!xIE4Up && !xOp7Up) && e==window) {
if(eT=='resize') { window.xREL=null; return; }
if(eT=='scroll') { window.xSEL=null; return; }
}
var eh='e.on'+eT+'=null';
if(e.removeEventListener) e.removeEventListener(eT,eL,cap);
else if(e.detachEvent) e.detachEvent('on'+eT,eL);
else eval(eh);
}
function xResizeTo(e,w,h)
{
xWidth(e,w);
xHeight(e,h);
}
function xScrollLeft(e, bWin)
{
var offset=0;
if (!xDef(e) || bWin || e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
var w = window;
if (bWin && e) w = e;
if(w.document.documentElement && w.document.documentElement.scrollLeft) offset=w.document.documentElement.scrollLeft;
else if(w.document.body && xDef(w.document.body.scrollLeft)) offset=w.document.body.scrollLeft;
}
else {
e = xGetElementById(e);
if (e && xNum(e.scrollLeft)) offset = e.scrollLeft;
}
return offset;
}
function xScrollTop(e, bWin)
{
var offset=0;
if (!xDef(e) || bWin || e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
var w = window;
if (bWin && e) w = e;
if(w.document.documentElement && w.document.documentElement.scrollTop) offset=w.document.documentElement.scrollTop;
else if(w.document.body && xDef(w.document.body.scrollTop)) offset=w.document.body.scrollTop;
}
else {
e = xGetElementById(e);
if (e && xNum(e.scrollTop)) offset = e.scrollTop;
}
return offset;
}
function xSetCookie(name, value, expire, path)
{
document.cookie = name + "=" + escape(value) +
((!expire) ? "" : ("; expires=" + expire.toGMTString())) +
"; path=" + ((!path) ? "/" : path);
}
function xShow(e) {return xVisibility(e,1);}
function xStr(s)
{
for(var i=0; i<arguments.length; ++i){if(typeof(arguments[i])!='string') return false;}
return true;
}
function xTop(e, iY)
{
if(!(e=xGetElementById(e))) return 0;
var css=xDef(e.style);
if(css && xStr(e.style.top)) {
if(xNum(iY)) e.style.top=iY+'px';
else {
iY=parseInt(e.style.top);
if(isNaN(iY)) iY=0;
}
}
else if(css && xDef(e.style.pixelTop)) {
if(xNum(iY)) e.style.pixelTop=iY;
else iY=e.style.pixelTop;
}
return iY;
}
function xVisibility(e, bShow)
{
if(!(e=xGetElementById(e))) return null;
if(e.style && xDef(e.style.visibility)) {
if (xDef(bShow)) e.style.visibility = bShow ? 'visible' : 'hidden';
return e.style.visibility;
}
return null;
}
function xWidth(e,w)
{
if(!(e=xGetElementById(e))) return 0;
if (xNum(w)) {
if (w<0) w = 0;
else w=Math.round(w);
}
else w=-1;
var css=xDef(e.style);
if (e == document || e.tagName.toLowerCase() == 'html' || e.tagName.toLowerCase() == 'body') {
w = xClientWidth();
}
else if(css && xDef(e.offsetWidth) && xStr(e.style.width)) {
if(w>=0) {
var pl=0,pr=0,bl=0,br=0;
if (document.compatMode=='CSS1Compat') {
var gcs = xGetComputedStyle;
pl=gcs(e,'padding-left',1);
if (pl !== null) {
pr=gcs(e,'padding-right',1);
bl=gcs(e,'border-left-width',1);
br=gcs(e,'border-right-width',1);
}
// Should we try this as a last resort?
// At this point getComputedStyle and currentStyle do not exist.
else if(xDef(e.offsetWidth,e.style.width)){
e.style.width=w+'px';
pl=e.offsetWidth-w;
}
}
w-=(pl+pr+bl+br);
if(isNaN(w)||w<0) return;
else e.style.width=w+'px';
}
w=e.offsetWidth;
}
else if(css && xDef(e.style.pixelWidth)) {
if(w>=0) e.style.pixelWidth=w;
w=e.style.pixelWidth;
}
return w;
}
function xZIndex(e,uZ)
{
if(!(e=xGetElementById(e))) return 0;
if(e.style && xDef(e.style.zIndex)) {
if(xNum(uZ)) e.style.zIndex=uZ;
uZ=parseInt(e.style.zIndex);
}
return uZ;
}
function xStopPropagation(evt)
{
if (evt && evt.stopPropagation) evt.stopPropagation();
else if (window.event) window.event.cancelBubble = true;
}

136
common/js/xml_handler.js Normal file
View file

@ -0,0 +1,136 @@
/**
* @file : common/js/xml_handler.js
* @author : zero <zero@nzeo.com>
* @desc : ajax 사용을 위한 기본 js
**/
// xml handler을 이용하는 user function
function exec_xml(method_name, act, params, callback_func, response_tags, callback_func_arg) {
var oXml = new xml_handler();
oXml.reset();
oXml.setMethod(method_name);
oXml.addParam('act', act);
for(var key in params) {
var val = params[key];
oXml.addParam(key, val);
}
var waiting_obj = document.getElementById('waitingforserverresponse');
waiting_obj.style.visibility = 'visible';
oXml.request(xml_response_filter, oXml, callback_func, response_tags, callback_func_arg);
}
// 결과 처리 후 callback_func에 넘겨줌
function xml_response_filter(oXml, callback_func, response_tags, callback_func_arg) {
var xmlDoc = oXml.getResponseXml();
if(!xmlDoc) return;
var waiting_obj = document.getElementById('waitingforserverresponse');
waiting_obj.style.visibility = 'hidden';
var ret_obj = oXml.toZMsgObject(xmlDoc, response_tags);
if(ret_obj['error']!=0) {
alert(ret_obj['message']);
return;
}
callback_func(ret_obj, response_tags, callback_func_arg);
}
// xml handler
function xml_handler() {
this.obj_xmlHttp = null;
this.method_name = null;
if(location.href.indexOf('admin.php')>0) this.xml_path = "./admin.php";
else this.xml_path = "./index.php";
this.params = new Array();
this.reset = xml_handlerReset;
this.getXmlHttp = zGetXmlHttp;
this.request = xml_handlerRequest;
this.setPath = xml_handlerSetPath;
this.setMethod = xml_handlerSetMethod;
this.addParam = xml_handlerAddParam;
this.getResponseXml = xml_handlerGetResponseXML;
this.toZMsgObject = xml_handlerToZMsgObject;
this.obj_xmlHttp = this.getXmlHttp();
}
function zGetXmlHttp() {
if (window.XMLHttpRequest) return new XMLHttpRequest();
else if (window.ActiveXObject) {
try {
return new ActiveXObject("Msxml2.XMLHTTP");
} catch (e) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
return null;
}
function xml_handlerRequest(callBackFunc, xmlObj, callBackFunc2, response_tags, callback_func_arg) {
var rd = "";
rd += "<?xml version=\"1.0\" encoding=\"utf-8\" ?>\n"
+ "<methodCall>\n"
+ "<methodName>"+this.method_name+"</methodName>\n"
+ "<params>\n"
for (var key in this.params) {
var val = this.params[key];
rd += "<"+key+"><![CDATA["+val+"]]></"+key+">\n";
}
rd += "</params>\n"
+ "</methodCall>\n";
if(this.obj_xmlHttp.readyState!=0) {
this.obj_xmlHttp.abort();
this.obj_xmlHttp = this.getXmlHttp();
}
this.obj_xmlHttp.onreadystatechange = function () {callBackFunc(xmlObj, callBackFunc2, response_tags, callback_func_arg)};
this.obj_xmlHttp.open('POST', this.xml_path, true);
this.obj_xmlHttp.send(rd);
}
function xml_handlerSetPath(path) {
this.xml_path = "./"+path;
}
function xml_handlerSetMethod(method_name) {
this.method_name = method_name;
}
function xml_handlerReset() {
this.obj_xmlHttp = this.getXmlHttp();
this.params = new Array();
}
function xml_handlerAddParam(key, val) {
this.params[key] = val;
}
function xml_handlerGetResponseXML() {
if(this.obj_xmlHttp && this.obj_xmlHttp.readyState == 4 && isDef(this.obj_xmlHttp.responseXML)) {
var xmlDoc = this.obj_xmlHttp.responseXML;
this.reset();
return xmlDoc;
}
return null;
}
function xml_handlerToZMsgObject(xmlDoc, tags) {
if(!xmlDoc) return null;
if(!tags) {
tags = new Array('error','message');
}
var obj_ret = new Array();
for(var i=0; i<tags.length; i++) {
try {
obj_ret[tags[i]] = xmlDoc.getElementsByTagName(tags[i])[0].firstChild.nodeValue;
} catch(e) {
obj_ret[tags[i]] = '';
}
}
return obj_ret;
}

230
common/js/xml_js_filter.js Normal file
View file

@ -0,0 +1,230 @@
/**
* @file : common/js/xml_js_filter.js
* @author : zero <zero@nzeo.com>
* @desc : xml filter에서 사용될 js
**/
var alertMsg = new Array();
// filtering
function XmlJsFilter(form_object, callback_user_func) {
this.fo_obj = null;
this.user_func = null;
this.field = new Array();
this.parameter = new Array();
this.response = new Array();
this.fo_obj = form_object;
this.user_func = callback_user_func;
this.addFieldItem = XmlJsFilterAddFieldItem;
this.addParameterItem = XmlJsFilterAddParameterItem;
this.addResponseItem = XmlJsFilterAddResponseItem;
this.getValue = XmlJsFilterGetValue;
this.executeFilter = XmlJsFilterExecuteFilter;
this.checkFieldItem = XmlJsFilterCheckFieldItem;
this.getParameterParam = XmlJsFilterGetParameterParam;
this.alertMsg = XmlJsFilterAlertMsg;
this.proc = XmlJsFilterProc;
}
function XmlJsFilterAddFieldItem(target, required, minlength, maxlength, equalto, filter) {
var obj = new Array(target, required, minlength, maxlength, equalto, filter);
this.field[this.field.length] = obj;
}
function XmlJsFilterAddParameterItem(param, target) {
var obj = new Array(param, target);
this.parameter[this.parameter.length] = obj;
}
function XmlJsFilterAddResponseItem(name) {
this.response[this.response.length] = name;
}
function XmlJsFilterGetValue(target_name) {
var obj = this.fo_obj[target_name];
if(typeof(obj)=='undefined') return '';
var value = '';
var length = obj.length;
var type = obj.type;
if(length) type = obj[0].type;
switch(type) {
case 'checkbox' :
if(typeof(length)!='undefined') {
value_list = new Array();
for(var i=0;i<obj.length;i++) {
if(obj[i].checked) value_list[value_list.length] = obj[i].value;
}
value = value_list.join(",");
} else {
if(obj.checked) value = obj.value;
else value = '';
}
break;
case 'radio' :
if(typeof(length)!='undefined') {
for(var i=0;i<obj.length;i++) {
if(obj[i].checked) value = obj[i].value;
}
} else {
if(obj.checked) value = obj.value;
else value = '';
}
break;
case 'select' :
case 'select-one' :
value = obj.options[obj.selectedIndex].value;
break;
default :
value = obj.value;
break;
}
if(typeof(value)=='undefined'||!value) return '';
return value.trim();
}
function XmlJsFilterExecuteFilter(filter, value) {
switch(filter) {
case "email" :
case "email_address" :
var regx = /^[_0-9a-zA-Z-]+(\.[_0-9a-zA-Z-]+)*@[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*$/;
return regx.test(value);
break;
case "userid" :
case "user_id" :
var regx = /^[a-zA-Z]+([_0-9a-zA-Z]+)*$/;
return regx.test(value);
break;
case "homepage" :
var regx = /(^[_0-9a-zA-Z-]+(\.[_0-9a-zA-Z-]+)*@[0-9a-zA-Z-]+(\.[0-9a-zA-Z-]+)*$)/;
return regx.test(value);
break;
case "korean" :
var regx = /^[가-힣]*$/;
return regx.test(value);
break;
case "korean_number" :
var regx = /^[가-힣0-9]*$/;
return regx.test(value);
break;
case "alpha" :
var regx = /^[a-zA-Z]*$/;
return regx.test(value);
break;
case "alpha_number" :
var regx = /^[a-zA-Z0-9]*$/;
return regx.test(value);
break;
case "number" :
return !isNaN(value);
break;
}
}
function XmlJsFilterAlertMsg(target, msg_code, minlength, maxlength) {
var target_msg = "";
if(alertMsg[target]!='undefined') target_msg = alertMsg[target];
else target_msg = target;
var msg = "";
if(typeof(alertMsg[msg_code])!='undefined') {
if(alertMsg[msg_code].indexOf('%s')>=0) msg = alertMsg[msg_code].replace('%s',target_msg);
else msg = target_msg+alertMsg[msg_code];
} else {
msg = msg_code;
}
if(typeof(minlength)!='undefined' && typeof(maxlength)!='undefined') msg += "("+minlength+"~"+maxlength+")";
alert(msg);
try {
this.fo_obj[target].focus();
} catch(e) {
}
return false;
}
function XmlJsFilterCheckFieldItem() {
for(var i=0; i<this.field.length;i++) {
var item = this.field[i];
var target = item[0];
var required = item[1];
var minlength = item[2];
var maxlength = item[3];
var equalto = item[4];
var filter = item[5].split(",");
var value = this.getValue(target);
if(!required && !value) return true;
if(required && !value) return this.alertMsg(target,'isnull');
if(minlength>0 && maxlength>0 && (value.length < minlength || value.length > maxlength)) return this.alertMsg(target, 'outofrange', minlength, maxlength);
if(equalto) {
var equalto_value = this.getValue(equalto);
if(equalto_value != value) return this.alertMsg(target, 'equalto');
}
if(filter.length && filter[0]) {
for(var j=0;j<filter.length;j++) {
var filter_item = filter[j];
if(!this.executeFilter(filter_item, value)) return this.alertMsg(target, "invalid_"+filter_item);
}
}
}
return true;
}
function XmlJsFilterGetParameterParam() {
var prev_name = '';
if(this.parameter.length<1) {
for(var i=0;i<this.fo_obj.length;i++) {
var name = this.fo_obj[i].name;
if(typeof(name)=='undefined'||!name||name==prev_name) continue;
this.addParameterItem(name, name);
prev_name = name;
}
}
var params = new Array();
for(var i=0; i<this.parameter.length;i++) {
var item = this.parameter[i];
var param = item[0];
var target = item[1];
var value = this.getValue(target);
params[param] = value;
}
return params;
}
function XmlJsFilterProc(confirm_msg) {
var result = this.checkFieldItem();
if(!result) return false;
if(typeof(confirm_msg)=='undefined') confirm_msg = '';
var params = this.getParameterParam();
var response = this.response;
var mid = params['mid'];
var act = params['act'];
if(confirm_msg && !confirm(confirm_msg)) return false;
if(!act) {
this.user_func(this.fo_obj, params);
return true;
}
exec_xml(mid, act, params, this.user_func, response, params);
}
// form proc
function procFormFilter(fo_obj, filter_func, user_func) {
filter_func(fo_obj, user_func);
return false;
}

135
common/lang/ko.lang.php Normal file
View file

@ -0,0 +1,135 @@
<?php
/**
* @file : common/lang/ko.lang.php
* @author : zero <zero@nzeo.com>
* @desc : 한국어 언어팩 (기본적인 내용만 수록)
**/
// 기본적으로 사용되는 action 언어
$lang->cmd_write = '쓰기';
$lang->cmd_reply = '답글';
$lang->cmd_delete = '삭제';
$lang->cmd_modify = '수정';
$lang->cmd_list = '목록';
$lang->cmd_prev = '이전';
$lang->cmd_next = '다음';
$lang->cmd_send_trackback = '엮인글발송';
$lang->cmd_registration = '등록';
$lang->cmd_save = '저장';
$lang->cmd_input = '입력';
$lang->cmd_search = '검색';
$lang->cmd_cancel = '취소';
$lang->cmd_back = '돌아가기';
$lang->cmd_vote= '추천';
$lang->cmd_login = '로그인';
$lang->cmd_logout = '로그아웃';
$lang->cmd_signup = '가입';
$lang->cmd_leave = '탈퇴';
$lang->cmd_move = '이동';
$lang->cmd_move_up = '위로';
$lang->cmd_move_down = '아래로';
$lang->cmd_management = '관리';
$lang->cmd_make = "생성";
$lang->cmd_select_all = "모두선택";
$lang->cmd_unselect_all = "모두해제";
$lang->enable = '가능';
$lang->disable = '불가능';
// 기본 단어
$lang->no = '번호';
$lang->notice = '공지';
$lang->secret = '비밀';
$lang->category = '분류';
$lang->document_srl = '문서번호';
$lang->user_id = '아이디';
$lang->author = '작성자';
$lang->password = '비밀번호';
$lang->password1 = '비밀번호';
$lang->password2 = '비밀번호 확인';
$lang->admin_id = '관리자ID';
$lang->user_name = '이름';
$lang->nick_name = '닉네임';
$lang->email_address = '이메일 주소';
$lang->homepage = '홈페이지';
$lang->browser_title = '브라우저 제목';
$lang->title = '제목';
$lang->title_content = '제목+내용';
$lang->content = '내용';
$lang->document = '게시물';
$lang->comment = '댓글';
$lang->description = '설명';
$lang->trackback = '엮인글';
$lang->tag = '태그';
$lang->about_tag = '태그 입력시 , (쉼표)를 이용하시면 복수 등록이 가능합니다';
$lang->allow_comment = '댓글허용';
$lang->lock_comment = '댓글잠금';
$lang->allow_trackback = '엮인글허용';
$lang->uploaded_file = '첨부파일';
$lang->grant = "권한";
$lang->target = "대상";
$lang->document_url = '게시글 주소';
$lang->trackback_url = '엮인글 주소';
$lang->blog_name = '블로그이름';
$lang->excerpt = '발췌';
$lang->document_count = '글수';
$lang->page_count = '페이지수';
$lang->readed_count = '조회수';
$lang->voted_count = '추천수';
$lang->member_count = '회원수';
$lang->date = '날짜';
$lang->regdate = '등록일';
$lang->last_update = '최근수정일';
$lang->last_login = '최종로그인';
$lang->first_page = '첫페이지';
$lang->last_page = '끝페이지';
$lang->search_target = '검색대상';
$lang->keyword = '검색어';
$lang->is_default = "기본";
$lang->use = "사용";
$lang->notuse = "미사용";
// xml filter에서 사용되는 javascript용 alert msg
$lang->filter->isnull = '%s의 값을 입력해주세요';
$lang->filter->outofrange = '%s의 글자 길이를 맞추어 주세요.';
$lang->filter->equalto = '%s의 값이 잘못 되었습니다.';
$lang->filter->invalid_email = '%s의 형식이 잘못되었습니다. (예: zb5@zeroboard.com)';
$lang->filter->invalid_user_id = $lang->filter->invalid_userid = "%s의 형식이 잘못되었습니다.\\n영문,숫자와 _로 만드실 수 있으며 제일 앞은 영문이어야 합니다";
$lang->filter->invalid_homepage = '%s의 형식이 잘못되었습니다. (예: http://www.zeroboard.com)';
$lang->filter->invalid_korean = '%s의 형식이 잘못되었습니다. 한글로만 입력해주셔야 합니다';
$lang->filter->invalid_korean_number = '%s의 형식이 잘못되었습니다. 한글과 숫자로만 입력해주셔야 합니다';
$lang->filter->invalid_alpha = '%s의 형식이 잘못되었습니다. 영문으로만 입력해주셔야 합니다';
$lang->filter->invalid_alpha_number = '%s의 형식이 잘못되었습니다. 영문과 숫자로만 입력해주셔야 합니다';
$lang->filter->invalid_number = '%s의 형식이 잘못되었습니다. 숫자로만 입력해주셔야 합니다';
// 메세지 관련
$lang->msg_call_server = '서버에 요청중입니다. 잠시만 기다려주세요.';
$lang->msg_db_not_setted = 'DB설정이 되어 있지 않습니다';
$lang->msg_mid_not_exists = '설정이 되어 있지 않습니다. 관리자 페이지에서 기본 설정을 해주시기 바랍니다.';
$lang->msg_invalid_queryid = 'Query ID값이 잘못 지정되었습니다';
$lang->msg_not_permitted = '권한이 없습니다';
$lang->msg_input_password = '비밀번호를 입력하여 주세요';
$lang->msg_invalid_document = '잘못된 문서번호입니다';
$lang->msg_invalid_request = '잘못된 요청입니다';
$lang->msg_invalid_password = '비밀번호가 올바르지 않습니다';
$lang->msg_error_occured = '오류가 발생하였습니다';
$lang->msg_not_founded = '대상을 찾을 수 없습니다';
$lang->success_registed = '등록되었습니다';
$lang->success_updated = '수정되었습니다';
$lang->success_deleted = '삭제되었습니다';
$lang->success_voted = '추천되었습니다';
$lang->success_moved = '이동되었습니다';
$lang->failed_voted = '추천하실 수 없습니다';
$lang->fail_to_delete_have_children = '답글이 있어서 삭제할 수 없습니다';
$lang->confirm_submit = '등록하시겠습니까?';
$lang->confirm_logout = '로그아웃하시겠습니까?';
$lang->confirm_vote = '추천하시겠습니까?';
$lang->confirm_delete = '삭제하시겠습니까?';
?>

View file

@ -0,0 +1,3 @@
<div id="waitingforserverresponse" >{$lang->msg_call_server}</div>
</body>
</html>

View file

@ -0,0 +1,19 @@
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="{Context::getLangType()}" xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>{Context::getBrowserTitle()}</title>
<script type='text/javascript' src='./common/js/x.js'></script>
<script type='text/javascript' src='./common/js/common.js'></script>
<script type='text/javascript' src='./common/js/xml_handler.js'></script>
<script type='text/javascript' src='./common/js/xml_js_filter.js'></script>
<!--@foreach(Context::getJsFile() as $key => $js_file)-->
<script type='text/javascript' src='{$js_file}'></script>
<!--@end-->
<link rel='stylesheet' HREF='./common/css/default.css' type='text/css' />
<!--@foreach(Context::getCssFile() as $key => $css_file)-->
<link rel='stylesheet' HREF='{$css_file}' type='text/css' />
<!--@end-->
{Context::getHtmlHeader()}
</head>
<body>

View file

@ -0,0 +1,3 @@
<!--#include("./common/tpl/common_header.html")-->
{$content}
<!--#include("./common/tpl/common_footer.html")-->

37
config/config.inc.php Normal file
View file

@ -0,0 +1,37 @@
<?php
/**
* @file : config/config.inc.php
* @author : zero <zero@nzeo.com>
* @desc : 기본적으로 사용하는 class파일의 include 환경 설정을
**/
// 기본적인 상수 선언
// 웹에서 직접 호출되는 것을 막기 위해 체크하는 상수 선언
define('__ZB5__', true);
// 기본 함수 라이브러리 파일
require_once("./config/func.inc.php");
// debug mode = true 일때 files/_debug_message.php 에 디버그 내용이 쌓임
define('__DEBUG__', true);
if(__DEBUG__) define('__StartTime__', getMicroTime());
// 세션 설정
@session_cache_limiter('no-cache, must-revalidate');
@session_start();
// 기본적인 class 파일 include
if(__DEBUG__) define('__RequireClassStartTime__', getMicroTime());
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/output/Output.class.php");
require_once("./classes/module/Module.class.php");
require_once("./classes/display/DisplayHandler.class.php");
require_once("./classes/module/ModuleHandler.class.php");
require_once('./modules/module_manager/module_manager.module.php');
//require_once("./classes/addon/AddOnHandler.class.php");
//require_once("./classes/layout/LayoutHandler.class.php");
if(__DEBUG__) define('__RequireClassEndTime__', getMicroTime());
?>

84
config/func.inc.php Normal file
View file

@ -0,0 +1,84 @@
<?php
/**
* @file : config/func.inc.php
* @author : zero <zero@nzeo.com>
* @desc : 편의 목적으로 만든 함수라이브러리 파일
**/
// php5에 대비하여 clone 정의/*{{{*/
if (version_compare(phpversion(), '5.0') < 0) {
eval('
function clone($object) {
return $object;
}
');
}/*}}}*/
// function object getModule($module_name, $is_admin=false)/*{{{*/
// module_manager::getModuleObject($module_name)을 쓰기 쉽게 함수로 선언
function getModule($module_name, $is_admin=false) {
if($is_admin) return module_manager::getAdminModuleObject($module_name);
return module_manager::getModuleObject($module_name);
}/*}}}*/
// function string getUrl($args_list)/*{{{*/
// Context::getUrl($args_list)를 쓰기 쉽게 함수로 선언
function getUrl() {
$num_args = func_num_args();
$args_list = func_get_args();
if(!$num_args) return Context::getRequestUri();
return Context::getUrl($num_args, $args_list);
}/*}}}*/
// function string cut_str($string, $cut_size, $tail = '...')/*{{{*/
// microtime
function cut_str($string, $cut_size, $tail='...') {
if(!$string || !$cut_size) return $string;
$unicode_str = iconv("UTF-8","UCS-2",$string);
if(strlen($unicode_str) < $cut_size*2) return $string;
$output = substr($unicode_str, 0, $cut_size*2);
return iconv("UCS-2","UTF-8",$output_str).$tail;
}/*}}}*/
// function string zdate($str, $format = "Y-m-d H:i:s")/*{{{*/
// 시간 출력
function zdate($str, $format = "Y-m-d H:i:s") {
return date($format, mktime(substr($str,8,2), substr($str,10,2), substr($str,12,2), substr($str,4,2), substr($str,6,2), substr($str,0,4)));
}/*}}}*/
// function void debugPrint($buff)/*{{{*/
// 간단한 console debugging용 함수
function debugPrint($buff, $display_line = true) {
$debug_file = "./files/_debug_message.php";
$buff = sprintf("%s\n",print_r($buff,true));
if($display_line) $buff = "\n====================================\n".$buff."------------------------------------\n";
if(@!$fp = fopen($debug_file,"a")) return;
fwrite($fp, $buff);
fclose($fp);
}/*}}}*/
// function float getMicroTime()/*{{{*/
// microtime
function getMicroTime() {
list($time1, $time2) = explode(' ', microtime());
return (float)$time1+(float)$time2;
}/*}}}*/
// function string delObjectVars($target_obj, $del_obj)/*{{{*/
// 첫번째 인자로 오는 object var에서 2번째 object의 var들을 빼낸다
function delObjectVars($target_obj, $del_obj) {
if(count(get_object_vars($target_obj))<1) return;
if(count(get_object_vars($del_obj))<1) clone($target_obj);
if(is_object($target_var)) $var = clone($target_var);
foreach($del_obj as $key => $val) {
unset($var->{$var_name});
}
return $var;
}/*}}}*/
?>

176
editor/default/editor.css Normal file
View file

@ -0,0 +1,176 @@
div.editor_content {
margin:3px;
}
div.editor_fontbox {
margin : 3px 3px 3px 0px;
float:left;
}
div.editor_fontbox select {
width:70px;
height:18px;
}
div.editor_iconbox {
margin : 3px 3px 3px 0px;
white-space:nowrap;
font-size:1pt;
float:left;
}
div.editor_iconbox img {
width : 16px;
height : 16px;
border : 1px solid #EEEEEE;
background-color : #FFFFFF;
padding:1px;
cursor : pointer;
margin-right:1px;
}
div.editor_parabox {
margin : 3px 3px 3px 0px;
font-size:9pt;
text-align:right;
display:none;
float:right;
}
div.editor_iframe_box {
clear:left;
border:1px solid #EFEFEF;
margin:3px 0px 0px 0px;
}
div.editor_drag_down_area {
width:100%;
height:15px;
background:url(./images/icon_drag_down.gif) no-repeat center;
background-color:#EFEFEF;
cursor:s-resize;
position:relative;
margin-top:10px;
}
.editor_pop_body {
padding:4px 4px 4px 4px;
margin:0px;
border:0px;
background-color:#FFFFFF;
}
.editor_window {
background-color : #EFEFEF;
}
textarea.editor_small_textarea {
font-family:tahoma;
border : 1px solid #CCCCCC;
background-color : #FFFFFF;
font-size : 8pt;
width:99%;
height:100px;
}
textarea.editor_textarea {
font-family:tahoma;
border : 1px solid #CCCCCC;
background-color : #FFFFFF;
font-size : 8pt;
width:100%;
height:450px;
}
input.editor_submit {
border : 1px solid #555555;
background-color : #AAAAAA;
color : #000000;
font-weight:bold;
font-family:verdana;
width : 100%;
height : 20px;
font-size : 8pt;
}
div.quotation_box {
font-size:8pt;
font-family:tahoma;
margin-bottom:8px;
padding-bottom:5px;
border-bottom:1px dotted #AAAAAA;
}
#quotation th { width:80px; font-size:8pt; font-family:tahoma; }
img.color_icon {
width:15px;
height:15px;
border:1px solid #FFFFFF;
}
img.color_icon_over {
width:15px;
height:15px;
border:1px solid #000000;
cursor:pointer;
}
td.editor_field {
font-family:tahoma;
font-size:8pt;
font-weight:bold;
background-color : #CCCCCC;
text-align : center;
}
input.editor_input {
font-family:tahoma;
border : 1px solid #CCCCCC;
background-color : #FFFFFF;
width : 330px;
height : 18px;
padding : 1px;
font-size : 8pt;
}
.editor_uploader_box {
margin:0px;
border:0px;
padding:0px;
}
.editor_uploader_box table {
border:0px;
margin:0px;
padding:2px;
table-layout:fixed;
width:100%;
}
.uploaded_file_preview_box {
border:1px solid #EEEEEE;
width:120px;
height:120px;
}
.uploaded_file_list {
width:100%;
height:120px;
}
.editor_align_icon {
margin:0px 0px 6px 5px;
font-size:9pt;
}
.editor_align_icon img {
vertical-align:middle;
cursor:pointer;
}
img.editor_multimedia {
background:url(./images/multimedia_icon.gif) no-repeat center;
background-color:#FFFFFF;
border:2px dotted #B7AD10;
}

View file

@ -0,0 +1,59 @@
<!--%import("editor.js")-->
<!--%import("editor.css")-->
<!-- 에디터 활성화 -->
<script type="text/javascript">
var editor_path = "{$editor_path}";
editorInit("{$document_srl}");
</script>
<!-- 에디터 -->
<div class="editor_content">
<div class="editor_fontbox">
<select onChange="editorChangeFontName(this,'{$document_srl}')" id="editor_font_{$document_srl}">
<option value="">{$lang->edit->fontname}</option>
<!--@foreach($lang->edit->fontlist as $key=>$obj)-->
<option style="font-family:{$obj}" value="{$obj}">{$obj}</option>
<!--@end-->
</select>
<select onChange="editorChangeFontSize(this,'{$document_srl}')" id="editor_fontsize_{$document_srl}">
<option value="" selected>{$lang->edit->fontsize}</option>
<option value="1">8pt</option>
<option value="2">10pt</option>
<option value="3">12pt</option>
<option value="4">14pt</option>
<option value="5">18pt</option>
<option value="6">24pt</option>
<option value="7">36pt</option>
</select>
</div>
<div class="editor_iconbox">
<img src="./images/font_color.gif" alt="{$lang->edit->help_fontcolor}" class="editor_icon" id="editor_ForeColor_{$document_srl}" />
<img src="./images/font_bg_color.gif" alt="{$lang->edit->help_fontbgcolor}" class="editor_icon" id="editor_BackColor_{$document_srl}" />
<img src="./images/bold.gif" alt="{$lang->edit->help_bold}" class="editor_icon" id="editor_Bold_{$document_srl}" />
<img src="./images/italic.gif" alt="{$lang->edit->help_italic}" class="editor_icon" id="editor_Italic_{$document_srl}" />
<img src="./images/underline.gif" alt="{$lang->edit->help_underline}" class="editor_icon" id="editor_Underline_{$document_srl}" />
<img src="./images/strike.gif" alt="{$lang->edit->help_strike}" class="editor_icon" id="editor_StrikeThrough_{$document_srl}" />
<img src="./images/add_url.gif" alt="{$lang->edit->help_add_url}" class="editor_icon" id="editor_addurl_{$document_srl}" />
<img src="./images/add_image.gif" alt="{$lang->edit->help_add_image}" class="editor_icon" id="editor_addimage_{$document_srl}" />
<img src="./images/add_multi.gif" alt="{$lang->edit->help_add_multimedia}" class="editor_icon" id="editor_addmultimedia_{$document_srl}" />
<img src="./images/emoticon.gif" alt="{$lang->edit->help_add_emoticon}" class="editor_icon" id="editor_addemoticon_{$document_srl}" />
<img src="./images/quotation.gif" alt="{$lang->edit->help_add_quotation}" class="editor_icon" id="editor_quotation_{$document_srl}" />
<img src="./images/html_add.gif" alt="{$lang->edit->help_add_html}" class="editor_icon" id="editor_addhtml_{$document_srl}" />
</div>
<div id="editor_paragraph_{$document_srl}" class="editor_iconbox" style="display:none">
<img src="./images/align_left.gif" alt="{$lang->edit->help_align_left}" id="editor_justifyleft_{$document_srl}" />
<img src="./images/align_center.gif" alt="{$lang->edit->help_align_center}" id="editor_justifycenter_{$document_srl}" />
<img src="./images/align_right.gif" alt="{$lang->edit->help_align_right}" id="editor_justifyright_{$document_srl}" />
<img src="./images/remove_indent.gif" alt="{$lang->edit->help_remove_indent}" id="editor_outdent_{$document_srl}" />
<img src="./images/add_indent.gif" alt="{$lang->edit->help_add_indent}" id="editor_indent_{$document_srl}" />
<img src="./images/list_number.gif" alt="list number" id="editor_insertorderedlist_{$document_srl}" />
<img src="./images/list_bullet.gif" alt="list bullet" id="editor_insertunorderedlist_{$document_srl}" />
</div>
<div class="editor_parabox" id="editor_use_paragraph_box_{$document_srl}">
<input type="checkbox" name="use_paragraph" id="editor_use_paragraph_{$document_srl}" onclick="editorUseParagraph(this,'{$document_srl}');" />
<label for="editor_use_paragraph_{$document_srl}">{$lang->edit->use_paragraph}</label>
</div>
<div class="editor_iframe_box"><iframe id="editor_iframe_{$document_srl}" frameBorder="0" style="border:0px;width:99%;height:300px;margin:0px;"></iframe><div class="editor_drag_down_area" id="editor_drag_bar_{$document_srl}"></div></div>
</div>

706
editor/default/editor.js Executable file
View file

@ -0,0 +1,706 @@
/**
* richtext 에디터 관련
**/
// iframe의 id prefix
var iframe_id = 'editor_iframe_';
// srl값에 해당하는 iframe의 object를 return
function editorGetIFrame(document_srl) {/*{{{*/
var obj_id = iframe_id+document_srl;
return xGetElementById(obj_id);
}/*}}}*/
// editor 초기화를 onload이벤트 후에 시작시킴
function editorInit(document_srl) {/*{{{*/
var start_func = function _editorStart() { editorStart(document_srl); }
var init_func = function _editorInit() { setTimeout(start_func, 300); }
xAddEventListener(window, 'load', init_func);
}/*}}}*/
// editor 초기화 (document_srl로 iframe객체를 얻어서 쓰기 모드로 전환)
function editorStart(document_srl) {/*{{{*/
// iframe obj를 찾음
var iframe_obj = editorGetIFrame(document_srl);
if(!iframe_obj) return;
// 현 에디터를 감싸고 있는 form문을 찾아서 content object를 찾아서 내용 sync
var fo_obj = iframe_obj.parentNode;
while(fo_obj.nodeName != 'FORM') { fo_obj = fo_obj.parentNode; }
var content = fo_obj.content.value;
// 기본 폰트를 가져옴
var default_font = xGetElementById('editor_font_'+document_srl).options[1].value;
// iframe내의 document object
var contentDocument = iframe_obj.contentWindow.document;
// editing가능하도록 설정
// 기본 내용 작성
var contentHtml = ''+
'<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">'+
'<html><head><meta http-equiv="content-type" content="text/html; charset=utf-8"/>';
/********* stylesheet
for(var i in document.styleSheets) {
var tmp_obj = document.styleSheets[i];
if(typeof(tmp_obj.href)=='undefined'||tmp_obj.href.lastIndexOf(".css")<0) continue;
contentHtml += "<link rel=\"StyleSheet\" HREF=\""+tmp_obj.href+"\" type=\"text/css\" />";
}
**********/
contentHtml += "<link rel=\"stylesheet\" href=\"./common/css/common.css\" type=\"text/css\" />";
contentHtml += "<link rel=\"stylesheet\" href=\""+editor_path+"/css/editor.css\" type=\"text/css\" />";
contentHtml += ""+
"</head><body style=\"background-color:#FFFFFF;font-family:"+default_font+";font-size:9pt;\">"+
content+
"</body></html>";
contentDocument.designMode = 'on';
contentDocument.open("text/html","replace");
contentDocument.write(contentHtml);
contentDocument.close();
// 작성시 필요한 이벤트 체크
if(xIE4Up) xAddEventListener(contentDocument, 'keydown',editorKeyPress);
else xAddEventListener(contentDocument, 'keypress',editorKeyPress);
xAddEventListener(contentDocument,'mousedown',editorHideObject);
//xAddEventListener(document,'keypress',editorKeyPress);
xAddEventListener(document,'mouseup',editorEventCheck);
xAddEventListener(document,'mousedown',editorHideObject);
// 문단작성기능 on/off
if(xIE4Up) {
xDisplay('editor_paragraph_'+document_srl, 'none');
xDisplay('editor_use_paragraph_box_'+document_srl, 'inline');
} else {
xDisplay('editor_paragraph_'+document_srl, 'block');
xDisplay('editor_use_paragraph_box_'+document_srl, 'none');
}
// 에디터의 내용을 지속적으로 fo_obj.content.value에 입력
editorSyncContent(fo_obj.content, document_srl);
}/*}}}*/
var _editorSyncList = new Array(); /*{{{*/
function editorSyncContent(obj, document_srl) {
_editorSyncList[_editorSyncList.length] = {field:obj, document_srl:document_srl}
}/*}}}*/
function _editorSync() {/*{{{*/
for(var i=0;i<_editorSyncList.length;i++) {
var field = _editorSyncList[i].field;
var document_srl = _editorSyncList[i].document_srl;
var content = editorGetContent(document_srl);
if(typeof(content)=='undefined'||!content) continue;
field.value = content;
}
setTimeout(_editorSync, 1000);
}/*}}}*/
xAddEventListener(window, 'load', _editorSync);
// 문단기능 toggle
function editorUseParagraph(obj, document_srl) { /*{{{*/
toggleDisplay('editor_paragraph_'+document_srl);
}/*}}}*/
// 에디터의 내용 return
function editorGetContent(document_srl) {/*{{{*/
var iframe_obj = editorGetIFrame(document_srl);
if(!iframe_obj) return;
var html = '';
html = xInnerHtml(iframe_obj.contentWindow.document.body);
if(!html) return;
return html.trim();
}/*}}}*/
// 에디터 내의 선택된 부분의 html 코드를 return
function editorGetSelectedHtml(document_srl) {/*{{{*/
var iframe_obj = editorGetIFrame(document_srl);
if(xIE4Up) {
var range = iframe_obj.contentWindow.document.selection.createRange();
var html = range.htmlText;
range.select();
return html;
} else {
var range = iframe_obj.contentWindow.getSelection().getRangeAt(0);
var dummy = xCreateElement('div');
dummy.appendChild(range.cloneContents());
var html = xInnerHtml(dummy);
return html;
}
}/*}}}*/
// 에디터 내의 선택된 부분의 html코드를 변경
function editorReplaceHTML(iframe_obj, html) {/*{{{*/
iframe_obj.contentWindow.focus();
if(xIE4Up) {
var range = iframe_obj.contentWindow.document.selection.createRange();
range.pasteHTML(html);
} else {
var range = iframe_obj.contentWindow.getSelection().getRangeAt(0);
range.deleteContents();
range.insertNode(range.createContextualFragment(html));
}
}/*}}}*/
// 입력 키에 대한 이벤트 체크
function editorKeyPress(evt) {/*{{{*/
var e = new xEvent(evt);
if (e.keyCode == 13) {
if(xIE4Up && e.shiftKey == false && !xGetElementById("use_paragraph").checked ) {
if(e.target.parentElement.document.designMode!="On") return;
var obj = e.target.parentElement.document.selection.createRange();
obj.pasteHTML('<br />');
obj.select();
evt.cancelBubble = true;
evt.returnValue = false;
return;
}
}
if (e.ctrlKey) {
switch(e.keyCode) {
case 98 : // b
editorDo('Bold',null,e.target);
xPreventDefault(evt);
xStopPropagation(evt);
break;
case 105 : // i
editorDo('Italic',null,e.target);
xPreventDefault(evt);
xStopPropagation(evt);
break;
case 117 : // u
editorDo('Underline',null,e.target);
xPreventDefault(evt);
xStopPropagation(evt);
break;
case 83 : // s
case 115 : // s
editorDo('StrikeThrough',null,e.target);
xPreventDefault(evt);
xStopPropagation(evt);
break;
}
}
}/*}}}*/
// 에디터 상단의 버튼 클릭시 action 처리
var editorPrevObj = null;/*{{{*/
var editorPrevSrl = null;
function editorEventCheck(evt) {
var e = new xEvent(evt);
var target_id = e.target.id;
if(target_id.indexOf('editor_')!=-1) {
var tmp_str = target_id.split('_');
var method_name = tmp_str[1];
var document_srl = tmp_str[2];
switch(method_name) {
case 'Bold' :
case 'Italic' :
case 'Underline' :
case 'StrikeThrough' :
case 'justifyleft' :
case 'justifycenter' :
case 'justifyright' :
case 'indent' :
case 'outdent' :
case 'insertorderedlist' :
case 'insertunorderedlist' :
editorDo(method_name, '', document_srl);
break;
default :
editorPrevSrl = document_srl;
switch(method_name) {
case "addemoticon" :
var x = (screen.availWidth - 225)/2;
var y = (screen.availHeight - 150)/2;
var editor_popup = window.open(editor_path+"popup/add_emoticon.php","_editorPopup","top="+y+",left="+x+",width=225,height=150,resizable=no,toolbars=no,scrollbars=no");
if(editor_popup) editor_popup.focus();
return;
break;
case "quotation" :
var x = (screen.availWidth - 400)/2;
var y = (screen.availHeight - 400)/2;
var editor_popup = window.open(editor_path+"popup/add_quotation.php","_editorPopup","top="+y+",left="+x+",width=400,height=400,resizable=no,toolbars=no,scrollbars=no");
if(editor_popup) editor_popup.focus();
return;
break;
case "addurl" :
var x = (screen.availWidth - 400)/2;
var y = (screen.availHeight - 220)/2;
var editor_popup = window.open(editor_path+"popup/add_url.php","_editorPopup","top="+y+",left="+x+",width=400,height=220,resizable=no,toolbars=no,scrollbars=no");
if(editor_popup) editor_popup.focus();
return;
break;
case "addimage" :
var x = (screen.availWidth - 420)/2;
var y = (screen.availHeight - 80)/2;
var editor_popup = window.open(editor_path+"popup/add_image.php","_editorPopup","top="+y+",left="+x+",width=420,height=80,resizable=no,toolbars=no,scrollbars=no");
if(editor_popup) editor_popup.focus();
return;
break;
case "addmultimedia" :
var x = (screen.availWidth - 400)/2;
var y = (screen.availHeight - 220)/2;
var editor_popup = window.open(editor_path+"popup/add_multi.php","_editorPopup","top="+y+",left="+x+",width=420,height=110,resizable=no,toolbars=no,scrollbars=no");
if(editor_popup) editor_popup.focus();
return;
break;
case "addhtml" :
var x = (screen.availWidth - 400)/2;
var y = (screen.availHeight - 500)/2;
var editor_popup = window.open(editor_path+"popup/add_html.php","_editorPopup","top="+y+",left="+x+",width=400,height=500,resizable=no,toolbars=no,scrollbars=no");
if(editor_popup) editor_popup.focus();
return;
break;
case "ForeColor" :
case "BackColor" :
var x = (screen.availWidth - 145)/2;
var y = (screen.availHeight - 95)/2;
var editor_popup = window.open(editor_path+"popup/color_box.php?mode="+method_name,"_editorPopup","top="+y+",left="+x+",width=145,height=95,resizable=no,toolbars=no,scrollbars=no");
if(editor_popup) editor_popup.focus();
return;
}
break;
}
}
return;
}/*}}}*/
// focus
function editorFocus(document_srl) {/*{{{*/
var iframe_obj = editorGetIFrame(document_srl);
iframe_obj.contentWindow.focus();
}
/*}}}*/
// 편집 기능 실행
function editorDo(name, value, target) {/*{{{*/
if(typeof(target)=='object') _editorDoObject(name, value, target);
else _editorDoSrl(name, value, target);
}/*}}}*/
function _editorDoSrl(name, value, document_srl) {/*{{{*/
var iframe_obj = editorGetIFrame(document_srl);
editorFocus(document_srl);
if(xIE4Up) iframe_obj.contentWindow.document.execCommand(name, false, value);
else iframe_obj.contentWindow.document.execCommand(name, false, value);
editorFocus(document_srl);
}/*}}}*/
function _editorDoObject(name, value, obj) {/*{{{*/
if(xIE4Up) {
obj.parentElement.document.execCommand(name, false, value);
} else {
obj.parentNode.execCommand(name, false, value);
}
}/*}}}*/
function editorHideObject(evt) {/*{{{*/
if(!editorPrevObj) return;
var e = new xEvent(evt);
var tobj = e.target;
while(tobj) {
if(tobj.id == editorPrevObj.id) {
return;
}
tobj = xParent(tobj);
}
editorPrevObj.style.visibility = 'hidden';
editorPrevObj = null;
return;
}/*}}}*/
function editorChangeFontName(obj,srl) {/*{{{*/
var value = obj.options[obj.selectedIndex].value;
if(!value) return;
editorDo('FontName',value,srl);
obj.selectedIndex = 0;
}/*}}}*/
function editorChangeFontSize(obj,srl) {/*{{{*/
var value = obj.options[obj.selectedIndex].value;
if(!value) return;
editorDo('FontSize',value,srl);
obj.selectedIndex = 0;
}/*}}}*/
function editorSetForeColor(color_code) {/*{{{*/
editorDo("ForeColor",color_code,editorPrevSrl);
editorPrevObj.style.visibility = 'hidden';
editorFocus(editorPrevSrl);
}/*}}}*/
function editorSetBackColor(color_code) {/*{{{*/
if(xIE4Up) editorDo("BackColor",color_code,editorPrevSrl);
else editorDo("hilitecolor",color_code,editorPrevSrl);
editorFocus(editorPrevSrl);
}/*}}}*/
function editorInsertEmoticon(obj) {/*{{{*/
editorFocus(editorPrevSrl);
editorDo("InsertImage",obj.src,editorPrevSrl);
editorFocus(editorPrevSrl);
}/*}}}*/
function editorDoInsertUrl(link, document_srl) {/*{{{*/
editorFocus(document_srl);
var iframe_obj = editorGetIFrame(srl);
editorReplaceHTML(iframe_obj, link);
}/*}}}*/
function editorInsertUrl(text, url, link_type) {/*{{{*/
if(!text || !url) return;
//if(!/^(http|ftp)/i.test(url)) url = 'http://'+url;
var link = '';
if(!link_type) link = "<a href=\""+url+"\" target=\"_blank\">"+text+"</a>";
else link = "<a href=\""+url+"\" class=\""+link_type+"\" style='text-decoration:none;' target=\"_blank\">"+text+"</a>";
editorFocus(editorPrevSrl);
var obj = editorGetIFrame(editorPrevSrl)
editorReplaceHTML(obj, link);
}/*}}}*/
function editorInsertImage(url, src_align) {/*{{{*/
if(!url) return;
//if(!/^(http|ftp)/i.test(url)) url = 'http://'+url;
editorFocus(editorPrevSrl);
var html = "<img src=\""+url+"\" border=\"0\" alt=\"i\" ";
if(typeof(src_align)!='undefined'&&src_align) html += " align=\""+src_align+"\"";
html += " />";
var obj = editorGetIFrame(editorPrevSrl);
editorReplaceHTML(obj, html);
}/*}}}*/
function editorGetMultimediaHtml(url, width, height, source_filename) {/*{{{*/
if(typeof(width)=='undefined'||!width) width = 540;
if(typeof(height)=='undefined'||!height) height= 420;
var type = "application/x-mplayer2";
var pluginspace = "http://www.microsoft.com/Windows/MediaPlayer/";
var kind = 'movie';
if(/\.swf$/i.test(url)) kind = 'flash';
if(typeof(source_filename)!='undefined' && /\.swf$/i.test(source_filename)) kind = 'flash';
if(kind=='flash') {
type = "application/x-shockwave-flash";
pluginspace = "http://www.macromedia.com/go/getflashplayer";
}
var html = "<embed src=\""+url+"\" width=\""+width+"\" height=\""+height+"\" autostart=\"0\" type=\""+type+"\" pluginspage=\""+pluginspace+"\"></embed><BR />";
return html;
}/*}}}*/
function editorInsertMultimedia(url, width, height) {/*{{{*/
if(url) {
var html = editorGetMultimediaHtml(url, width, height);
editorFocus(editorPrevSrl);
var obj = editorGetIFrame(editorPrevSrl)
editorReplaceHTML(obj, html);
editorFocus(editorPrevSrl);
}
}/*}}}*/
function editorInsertHTML(html) {/*{{{*/
if(!html) return;
editorFocus(editorPrevSrl);
var obj = editorGetIFrame(editorPrevSrl)
editorReplaceHTML(obj, html);
editorFocus(editorPrevSrl);
}/*}}}*/
function editorInsertQuotation(html) {/*{{{*/
if(!html) return;
if(!xIE4Up) html += "<br />";
editorFocus(editorPrevSrl);
var obj = editorGetIFrame(editorPrevSrl)
editorReplaceHTML(obj, html);
editorFocus(editorPrevSrl);
}/*}}}*/
function editorHighlight(ret_obj, response_tags, obj) {/*{{{*/
var html = ret_obj['html'];
html = "<div class='php_code'>"+html+"</div>";
if(!xIE4Up) html += "<br />";
editorReplaceHTML(obj, html);
}/*}}}*/
/**
* iframe 드래그 관련
**/
var editorIsDrag = false;
var editorDragY = 0;
var editorDragObj = null;
var editorDragID = '';
xAddEventListener(document, 'mousedown', editorDragStart);
xAddEventListener(document, 'mouseup', editorDragStop);
function editorDragStart(evt) {/*{{{*/
var e = new xEvent(evt);
var obj = e.target;
if(typeof(obj.id)=='undefined'||!obj.id) return;
var id = obj.id;
if(id.indexOf('editor_drag_bar_')!=0) return;
editorIsDrag = true;
editorDragObj = e.target;
editorDragY = e.pageY;
editorDragID = id.substr('editor_drag_bar_'.length);
xAddEventListener(document, 'mousemove', editorDragMove);
xAddEventListener(editorDragObj, 'mouseout', editorDragMove);
var iframe_obj = editorGetIFrame(editorDragID);
xAddEventListener(iframe_obj, 'mousemove', editorDragMove);
}/*}}}*/
function editorDragStop(evt) {/*{{{*/
var iframe_obj = editorGetIFrame(editorDragID);
xRemoveEventListener(document, 'mousemove', editorDragMove);
xRemoveEventListener(iframe_obj, 'mousemove', editorDragMove);
editorIsDrag = false;
editorDragY = 0;
editorDragObj = null;
editorDragID = '';
}/*}}}*/
function editorDragMove(evt) {/*{{{*/
if(typeof(editorIsDrag)=='undefined'||!editorIsDrag) return;
var e = new xEvent(evt);
var iframe_obj = editorGetIFrame(editorDragID);
var y = e.pageY;
var yy = y - editorDragY;
if(yy<0) return;
editorDragY = y;
var editorHeight = xHeight(iframe_obj);
xHeight(iframe_obj, editorHeight+yy);
}/*}}}*/
/**
* 파일 업로드 관련
**/
var uploading_file = false;
var uploaded_files = new Array();
// 업로드를 하기 위한 준비 시작
function editor_upload_init(document_srl) {/*{{{*/
xAddEventListener(window,'load',function _change_form_target() {editor_upload_form_set(document_srl);} );
}/*}}}*/
// document_srl에 해당하는 form의 action을 iframe으로 변경
function editor_upload_form_set(document_srl) {/*{{{*/
// 업로드용 iframe을 생성
if(!xGetElementById('tmp_upload_iframe')) {
if(xIE4Up) {
window.document.body.insertAdjacentHTML("afterEnd", "<iframe name='tmp_upload_iframe' style='display:none;width:1px;height:1px;position:absolute;top:-10px;left:-10px'></iframe>");
} else {
var obj_iframe = xCreateElement('IFRAME');
obj_iframe.name = obj_iframe.id = 'tmp_upload_iframe';
obj_iframe.style.display = 'none';
obj_iframe.style.width = '1px';
obj_iframe.style.height = '1px';
obj_iframe.style.position = 'absolute';
obj_iframe.style.top = '-10px';
obj_iframe.style.left = '-10px';
window.document.body.appendChild(obj_iframe);
}
}
// form의 action 을 변경
var field_obj = xGetElementById("uploaded_file_list_"+document_srl);
if(!field_obj) return;
var fo_obj = field_obj.parentNode;
while(fo_obj.nodeName != 'FORM') { fo_obj = fo_obj.parentNode; }
fo_obj.target = 'tmp_upload_iframe';
// document_srl에 해당하는 첨부파일 목록을 로드
var mid = fo_obj.mid.value;
var document_srl = fo_obj.document_srl.value;
var url = "./?mid="+mid+"&act=procDeleteFile&document_srl="+document_srl;
// iframe에 url을 보내버림
var iframe_obj = xGetElementById('tmp_upload_iframe');
if(!iframe_obj) return;
iframe_obj.contentWindow.document.location.href=url;
}/*}}}*/
// 파일 업로드
function editor_file_upload(field_obj, document_srl) {/*{{{*/
if(uploading_file) return;
var fo_obj = field_obj.parentNode;
while(fo_obj.nodeName != 'FORM') { fo_obj = fo_obj.parentNode; }
uploading_file = true;
fo_obj.submit();
uploading_file = false;
var sel_obj = xGetElementById('uploaded_file_list_'+document_srl);
var string = 'wait for uploading...';
var opt_obj = new Option(string, '', true, true);
sel_obj.options[sel_obj.options.length] = opt_obj;
}/*}}}*/
// 업로드된 파일 목록을 삭제
function editor_upload_clear_list(document_srl) {/*{{{*/
var obj = xGetElementById('uploaded_file_list_'+document_srl);
while(obj.options.length) {
obj.remove(0);
}
var preview_obj = xGetElementById('uploaded_file_preview_box_'+document_srl);
xInnerHtml(preview_obj,'')
}/*}}}*/
// 업로드된 파일 정보를 목록에 추가
function editor_insert_uploaded_file(document_srl, file_srl, filename, file_size, disp_file_size, uploaded_filename, sid) {/*{{{*/
var obj = xGetElementById('uploaded_file_list_'+document_srl);
var string = filename+' ('+disp_file_size+')';
var opt_obj = new Option(string, file_srl, true, true);
obj.options[obj.options.length] = opt_obj;
var file_obj = {file_srl:file_srl, filename:filename, file_size:file_size, uploaded_filename:uploaded_filename, sid:sid}
uploaded_files[file_srl] = file_obj;
editor_preview(obj, document_srl);
}/*}}}*/
// 파일 목록창에서 클릭 되었을 경우 미리 보기
function editor_preview(sel_obj, document_srl) {/*{{{*/
if(sel_obj.options.length<1) return;
var file_srl = sel_obj.options[sel_obj.selectedIndex].value;
var obj = uploaded_files[file_srl];
if(typeof(obj)=='undefined'||!obj) return;
var uploaded_filename = obj.uploaded_filename;
var preview_obj = xGetElementById('uploaded_file_preview_box_'+document_srl);
if(!uploaded_filename) {
xInnerHtml(preview_obj, '');
return;
}
var html = "";
// 플래쉬 동영상의 경우
if(/\.flv$/i.test(uploaded_filename)) {
html = "<EMBED src=\""+editor_path+"flvplayer/flvplayer.swf?autoStart=true&file="+uploaded_filename+"\" width=\"120\" height=\"120\" type=\"application/x-shockwave-flash\"></EMBED>";
// 플래쉬 파일의 경우
} else if(/\.swf$/i.test(uploaded_filename)) {
html = "<EMBED src=\""+uploaded_filename+"\" width=\"120\" height=\"120\" type=\"application/x-shockwave-flash\"></EMBED>";
// wmv, avi, mpg, mpeg등의 동영상 파일의 경우
} else if(/\.(wmv|avi|mpg|mpeg|asx|asf|mp3)$/i.test(uploaded_filename)) {
html = "<EMBED src=\""+uploaded_filename+"\" width=\"120\" height=\"120\" autostart=\"true\" Showcontrols=\"0\"></EMBED>";
// 이미지 파일의 경우
} else if(/\.(jpg|jpeg|png|gif)$/i.test(uploaded_filename)) {
html = "<img src=\""+uploaded_filename+"\" border=\"0\" width=\"120\" height=\"120\" />";
}
xInnerHtml(preview_obj, html);
}/*}}}*/
// 업로드된 파일 삭제
function editor_remove_file(document_srl) {/*{{{*/
var obj = xGetElementById('uploaded_file_list_'+document_srl);
if(obj.options.length<1) return;
var file_srl = obj.options[obj.selectedIndex].value;
if(!file_srl) return;
// 삭제하려는 파일의 정보를 챙김;;
var fo_obj = obj;
while(fo_obj.nodeName != 'FORM') { fo_obj = fo_obj.parentNode; }
var mid = fo_obj.mid.value;
var document_srl = fo_obj.document_srl.value;
var url = "./?mid="+mid+"&act=procDeleteFile&document_srl="+document_srl+"&file_srl="+file_srl;
// iframe에 url을 보내버림
var iframe_obj = xGetElementById('tmp_upload_iframe');
if(!iframe_obj) return;
iframe_obj.contentWindow.document.location.href=url;
}/*}}}*/
// 업로드 목록의 선택된 파일을 내용에 추가
function editor_insert_file(document_srl, align) {/*{{{*/
var obj = xGetElementById('uploaded_file_list_'+document_srl);
if(obj.options.length<1) return;
var file_srl = obj.options[obj.selectedIndex].value;
if(!file_srl) return;
var file_obj = uploaded_files[file_srl];
var filename = file_obj.filename;
var sid = file_obj.sid;
var uploaded_filename = file_obj.uploaded_filename;
editorPrevSrl = document_srl;
// 바로 링크 가능한 파일의 경우 (이미지, 플래쉬, 동영상 등..)
if(uploaded_filename && typeof(align)!='undefined') {
var type = "";
// 이미지 파일의 경우
if(/\.(jpg|jpeg|png|gif)$/i.test(uploaded_filename)) {
editorFocus(editorPrevSrl);
var html = "<img src=\""+uploaded_filename+"\" border=\"0\" alt=\""+filename+"\" ";
if(typeof(align)!='undefined'&&align) html += " align=\""+align+"\"";
html += " />"
var obj = editorGetIFrame(editorPrevSrl);
editorReplaceHTML(obj, html);
// 이미지외의 경우는 대체 이미지를 넣음
} else {
// 플래쉬 동영상의 경우
if(/\.flv$/i.test(uploaded_filename)) {
type = "flv";
uploaded_filename = editor_path+"flvplayer/flvplayer.swf?autoStart=true&file="+uploaded_filename;
// 플래쉬 파일의 경우
} else if(/\.swf$/i.test(uploaded_filename)) {
type = "swf";
// wmv, avi, mpg, mpeg등의 동영상 파일의 경우
} else if(/\.(wmv|avi|mpg|mpeg)$/i.test(uploaded_filename)) {
type = "multimedia";
}
var alt = "align="+align+"|@|src="+uploaded_filename+"|@|type="+type;
var html = "<img src=\""+editor_path+"images/blank.gif\" style=\"width:400px;height:300px;\" alt=\""+alt+"\" class=\"editor_multimedia\"/>";
var iframe_obj = editorGetIFrame(editorPrevSrl);
editorReplaceHTML(iframe_obj, html);
}
// binary파일의 경우 다운로드 링크를 추가
} else {
var fo_obj = obj;
while(fo_obj.nodeName != 'FORM') { fo_obj = fo_obj.parentNode; }
var mid = fo_obj.mid.value;
var document_srl = fo_obj.document_srl.value;
var url = "./?mid="+mid+"&amp;act=procDownload&amp;document_srl="+document_srl+"&amp;file_srl="+file_srl+"&amp;sid="+sid;
var x = (screen.availWidth - 400)/2;
var y = (screen.availHeight - 220)/2;
var editor_popup = window.open(editor_path+"popup/add_url.php?title="+escape(filename)+"&url="+escape(url),"_editorPopup","top="+y+",left="+x+",width=400,height=220,resizable=no,toolbars=no,scrollbars=no");
if(editor_popup) editor_popup.focus();
}
}/*}}}*/
/**
* 글을 쓰다가 페이지 이동시 첨부파일에 대한 정리
**/
function editorRemoveAttachFiles(mid, document_srl) {/*{{{*/
var obj = xGetElementById('uploaded_file_list_'+document_srl);
if(obj.options.length<1) return;
var params = new Array();
params['document_srl'] = document_srl;
exec_xml(mid, 'procClearFile', params, null, null, null);
}/*}}}*/

View file

@ -0,0 +1,44 @@
<!--@if($grant->fileupload)-->
<script type="text/javascript">
editor_upload_init("{$document_srl}");
xAddEventListener(window, 'beforeunload', function _editorRemoveAttachFiles{$document_srl}() { editorRemoveAttachFiles("{$mid}","{$document_srl}"); });
</script>
<div class="editor_uploader_box">
<table>
<tr valign="top">
<td width="125"><div id="uploaded_file_preview_box_{$document_srl}" class="uploaded_file_preview_box"></div></td>
<td width="150">
<div class="editor_align_icon">
<img src="./images/icon_align_article.gif" border="0" onclick="editor_insert_file('{$document_srl}', '');" alt="{$lang->edit->icon_align_article}"/>
{$lang->edit->icon_align_article}
</div>
<div class="editor_align_icon">
<img src="./images/icon_align_left.gif" border="0" onclick="editor_insert_file('{$document_srl}', 'left');" alt="{$lang->edit->icon_align_left}"/>
{$lang->edit->icon_align_left}
</div>
<div class="editor_align_icon">
<img src="./images/icon_align_middle.gif" border="0" onclick="editor_insert_file('{$document_srl}', 'middle');" alt="{$lang->edit->icon_align_middle}"/>
{$lang->edit->icon_align_middle}
</div>
<div class="editor_align_icon">
<img src="./images/icon_align_right.gif" border="0" onclick="editor_insert_file('{$document_srl}', 'right');" alt="{$lang->edit->icon_align_right}"/>
{$lang->edit->icon_align_right}
</div>
</td>
<td><select id='uploaded_file_list_{$document_srl}' size='9' class="uploaded_file_list" onclick="editor_preview(this, '{$document_srl}')"></select></td>
</tr>
<tr>
<td>
<input type="button" value="{$lang->edit->delete_selected}" onclick="editor_remove_file('{$document_srl}');return false;" style="width:100%;"/>
</td>
<td>
<input type="button" value="{$lang->edit->link_selected}" onclick="editor_insert_file('{$document_srl}');return false;" style="width:100%;"/>
</td>
<td align="right">
<input type="file" name="file" onchange="editor_file_upload(this, '{$document_srl}')" value="{$lang->edit->upload}" style="width:100%;" />
</td>
</tr>
</table>
</div>
<!--@end-->

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,019 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 510 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 307 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 308 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 323 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 49 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,018 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,022 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,015 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,015 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,022 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 944 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,013 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 975 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,007 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,016 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 977 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 989 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 980 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 971 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 968 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 987 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 992 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 953 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 549 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1,023 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 379 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 366 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 382 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 368 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 53 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 302 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 304 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 603 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 547 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 525 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 309 B

Some files were not shown because too many files have changed in this diff Show more