Json 지원

git-svn-id: http://xe-core.googlecode.com/svn/sandbox@4744 201d5d3c-b55e-5fd7-737f-ddc643e51545
This commit is contained in:
ngleader 2008-11-03 09:32:57 +00:00
parent 4939b325f8
commit 40326eec5f
7 changed files with 292 additions and 33 deletions

View file

@ -108,6 +108,7 @@
// Request Argument 설정
$this->_setXmlRpcArgument();
$this->_setJSONRequestArgument();
$this->_setRequestArgument();
$this->_setUploadedArgument();
@ -492,7 +493,7 @@
/**
* @brief response method를 강제로 지정 (기본으로는 request method를 이용함)
*
* method의 종류에는 HTML/ TEXT/ XMLRPC있음
* method의 종류에는 HTML/ TEXT/ XMLRPC/ JSON있음
**/
function setResponseMethod($method = "HTML") {
$oContext = &Context::getInstance();
@ -517,12 +518,14 @@
function _getResponseMethod() {
if($this->response_method) return $this->response_method;
if($this->_getRequestMethod()=="XMLRPC") return "XMLRPC";
$RequestMethod = $this->_getRequestMethod();
if($RequestMethod=="XMLRPC") return "XMLRPC";
else if($RequestMethod=="JSON") return "JSON";
return "HTML";
}
/**
* @brief request method가 어떤것인지 판단하여 저장 (GET/POST/XMLRPC)
* @brief request method가 어떤것인지 판단하여 저장 (GET/POST/XMLRPC/JSON)
**/
function setRequestMethod($type) {
$oContext = &Context::getInstance();
@ -531,11 +534,12 @@
/**
* @brief request method가 어떤것인지 판단하여 저장 (GET/POST/XMLRPC)
* @brief request method가 어떤것인지 판단하여 저장 (GET/POST/XMLRPC/JSON)
**/
function _setRequestMethod($type = '') {
if($type) return $this->request_method = $type;
if(strpos($_SERVER['CONTENT_TYPE'],'json')) return $this->request_method = 'JSON';
if($GLOBALS['HTTP_RAW_POST_DATA']) return $this->request_method = "XMLRPC";
$this->request_method = $_SERVER['REQUEST_METHOD'];
@ -558,6 +562,22 @@
}
}
/**
* @brief JSON 방식일 경우 처리
**/
function _setJSONRequestArgument() {
if($this->_getRequestMethod() != 'JSON') return;
// if(!$GLOBALS['HTTP_RAW_POST_DATA']) return;
$params = array();
parse_str($GLOBALS['HTTP_RAW_POST_DATA'],$params);
foreach($params as $key => $val) {
$val = $this->_filterRequestVar($key, $val);
$this->_set($key, $val, true);
}
}
/**
* @brief XML RPC일때
**/
@ -571,7 +591,6 @@
unset($params->attrs);
if(!count($params)) return;
foreach($params as $key => $obj) {
$val = $this->_filterRequestVar($key, $obj->body);
$this->_set($key, $val, true);
@ -629,7 +648,7 @@
}
/**
* @brief Request Method값을 return (GET/POST/XMLRPC);
* @brief Request Method값을 return (GET/POST/XMLRPC/JSON);
**/
function getRequestMethod() {
$oContext = &Context::getInstance();
@ -637,7 +656,7 @@
}
/**
* @brief Request Method값을 return (GET/POST/XMLRPC);
* @brief Request Method값을 return (GET/POST/XMLRPC/JSON);
**/
function _getRequestMethod() {
return $this->request_method;

View file

@ -26,13 +26,13 @@
// header 출력
$this->_printHeader();
// request method에 따른 처리
if(Context::getRequestMethod() == 'XMLRPC') $content = $this->_toXmlDoc($oModule);
else if(Context::getRequestMethod() == 'JSON') $content = $this->_toJSON($oModule);
else $content = $this->_toHTMLDoc($oModule);
// 요청방식에 따라 출력을 별도로
if(Context::getResponseMethod()!="XMLRPC") {
if(Context::getResponseMethod()=="HTML") {
Context::set('content', $content);
@ -93,6 +93,17 @@
else print $content;
}
/**
* @brief RequestMethod가 JSON이면 JSON 데이터로 컨텐츠 생성
**/
function _toJSON(&$oModule) {
$variables = $oModule->getVariables();
//if(function_exists('json_encode')) return json_encode($variables);
//else return json_encode2($variables);
return json_encode2($variables);
}
/**
* @brief RequestMethod가 XML이면 XML 데이터로 컨텐츠 생성
**/
@ -209,7 +220,8 @@
***/
function _printHeader() {
if($this->gz_enabled) header("Content-Encoding: gzip");
if(Context::getResponseMethod() != 'HTML') return $this->_printXMLHeader();
if(Context::getResponseMethod() == 'JSON') return $this->_printJSONHeader();
else if(Context::getResponseMethod() != 'HTML') return $this->_printXMLHeader();
else return $this->_printHTMLHeader();
}
@ -236,5 +248,17 @@
header("Cache-Control: post-check=0, pre-check=0", false);
header("Pragma: no-cache");
}
/**
* @brief JSON header 출력 (utf8 고정)
**/
function _printJSONHeader() {
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

@ -188,7 +188,7 @@
}
// XMLRPC call 이 아니면 message view 객체 이용하도록
if(Context::getRequestMethod() != 'XMLRPC') {
if(Context::getRequestMethod() != 'XMLRPC' && Context::getRequestMethod() != 'JSON') {
// 에러가 발생하였을시 처리
if($this->error) {
// message 모듈 객체를 생성해서 컨텐츠 생성

View file

@ -350,7 +350,7 @@
}
// view action이고 결과 출력이 XMLRPC일 경우 해당 모듈의 api method를 실행
if(Context::getResponseMethod() == 'XMLRPC' && $this->module_info->module_type == 'view') {
if((Context::getResponseMethod() == 'XMLRPC' || Context::getResponseMethod() == 'JSON') && $this->module_info->module_type == 'view') {
$oAPI = getAPI($this->module_info->module, 'api');
if(method_exists($oAPI, $this->act)) {
$oAPI->{$this->act}($this);

View file

@ -398,6 +398,7 @@ function chkPopupMenu(evt) {
// 이벤트 대상이 없으면 무시
var e = new xEvent(evt);
if(!e) return;
// 대상의 객체 구함
@ -437,14 +438,15 @@ function chkPopupMenu(evt) {
// action이름을 규칙에 맞게 작성
var action_name = "get" + module_name.substr(0,1).toUpperCase() + module_name.substr(1,module_name.length-1) + "Menu";
// 서버에 메뉴를 요청
var params = new Array();
params["target_srl"] = target_srl;
params["cur_mid"] = current_mid;
params["cur_act"] = current_url.getQuery('act');
params["menu_id"] = menu_id;
params["page_x"] = e.pageX;
params["page_y"] = e.pageY;
params["page_x"] = e.pageX >0 ? e.pageX : GetObjLeft(obj);
params["page_y"] = e.pageY >0 ? e.pageY : GetObjTop(obj)+ xHeight(obj);
var response_tags = new Array("error","message","menus");
@ -458,6 +460,15 @@ function chkPopupMenu(evt) {
}
function GetObjTop(obj) {
if(obj.offsetParent == document.body) return xOffsetTop(obj);
else return xOffsetTop(obj) + GetObjTop(obj.offsetParent);
}
function GetObjLeft(obj) {
if(obj.offsetParent == document.body) return xOffsetLeft(obj);
else return xOffsetLeft(obj) + GetObjLeft(obj.offsetParent);
}
function displayPopupMenu(ret_obj, response_tags, params) {
var target_srl = params["target_srl"];
@ -558,7 +569,7 @@ function displayPopupMenu(ret_obj, response_tags, params) {
// 레이어 출력
if(html) {
var area = xGetElementById("popup_menu_area");
xInnerHtml(area, "<ul>"+html+"</ul>");
xInnerHtml(area, '<ul>'+html+'</ul>');
xLeft(area, params["page_x"]);
xTop(area, params["page_y"]);
if(xWidth(area)+xLeft(area)>xClientWidth()+xScrollLeft()) xLeft(area, xClientWidth()-xWidth(area)+xScrollLeft());

View file

@ -78,7 +78,7 @@ function zGetXmlHttp() {
} catch (e) {
return new ActiveXObject("Microsoft.XMLHTTP");
}
}
}
return null;
}
@ -160,12 +160,20 @@ function xml_handlerGetResponseXML() {
return null;
}
function xml_parseXmlDoc(dom) {
if(!dom) return;
var jsonStr = xml2json(dom,false,false);
var jsonObj = eval("("+ jsonStr +");");
return jsonObj.response;
/*
var ret_obj = new Array();
var obj = dom.firstChild;
var preObj;
if(!obj) return;
while(obj) {
@ -175,11 +183,11 @@ function xml_parseXmlDoc(dom) {
var value = null;
if(obj.childNodes.length==1 && obj.firstChild.nodeType != 1) {
value = obj.firstChild.nodeValue;
} else {
value = this.parseXMLDoc(obj);
}
if(typeof(ret_obj[name])=='undefined') {
ret_obj[name] = value;
} else {
@ -195,8 +203,10 @@ function xml_parseXmlDoc(dom) {
}
obj = obj.nextSibling;
}
return ret_obj;
*/
}
function xml_handlerToZMsgObject(xmlDoc, tags) {
@ -215,3 +225,164 @@ function xml_handlerToZMsgObject(xmlDoc, tags) {
}
return obj_ret;
}
/* This work is licensed under Creative Commons GNU LGPL License.
License: http://creativecommons.org/licenses/LGPL/2.1/
Version: 0.9
Author: Stefan Goessner/2006
Web: http://goessner.net/
*/
function xml2json(xml, tab, ignoreAttrib) {
var X = {
toObj: function(xml) {
var o = {};
if (xml.nodeType==1) { // element node ..
if (ignoreAttrib && xml.attributes.length) // element with attributes ..
for (var i=0; i<xml.attributes.length; i++)
o["@"+xml.attributes[i].nodeName] = (xml.attributes[i].nodeValue||"").toString();
if (xml.firstChild) { // element has child nodes ..
var textChild=0, cdataChild=0, hasElementChild=false;
for (var n=xml.firstChild; n; n=n.nextSibling) {
if (n.nodeType==1) hasElementChild = true;
else if (n.nodeType==3 && n.nodeValue.match(/[^ \f\n\r\t\v]/)) textChild++; // non-whitespace text
else if (n.nodeType==4) cdataChild++; // cdata section node
}
if (hasElementChild) {
if (textChild < 2 && cdataChild < 2) { // structured element with evtl. a single text or/and cdata node ..
X.removeWhite(xml);
for (var n=xml.firstChild; n; n=n.nextSibling) {
if (n.nodeType == 3) // text node
o = X.escape(n.nodeValue);
else if (n.nodeType == 4) // cdata node
// o["#cdata"] = X.escape(n.nodeValue);
o = X.escape(n.nodeValue);
else if (o[n.nodeName]) { // multiple occurence of element ..
if (o[n.nodeName] instanceof Array)
o[n.nodeName][o[n.nodeName].length] = X.toObj(n);
else
o[n.nodeName] = [o[n.nodeName], X.toObj(n)];
}
else // first occurence of element..
o[n.nodeName] = X.toObj(n);
}
}
else { // mixed content
if (!xml.attributes.length)
o = X.escape(X.innerXml(xml));
else
o["#text"] = X.escape(X.innerXml(xml));
}
}
else if (textChild) { // pure text
if (!xml.attributes.length)
o = X.escape(X.innerXml(xml));
else
o["#text"] = X.escape(X.innerXml(xml));
}
else if (cdataChild) { // cdata
if (cdataChild > 1)
o = X.escape(X.innerXml(xml));
else
for (var n=xml.firstChild; n; n=n.nextSibling){
//o["#cdata"] = X.escape(n.nodeValue);
o = X.escape(n.nodeValue);
}
}
}
if (!xml.attributes.length && !xml.firstChild) o = null;
}
else if (xml.nodeType==9) { // document.node
o = X.toObj(xml.documentElement);
}
else
alert("unhandled node type: " + xml.nodeType);
return o;
},
toJson: function(o, name, ind) {
var json = name ? ("\""+name+"\"") : "";
if (o instanceof Array) {
for (var i=0,n=o.length; i<n; i++)
o[i] = X.toJson(o[i], "", ind+"\t");
json += (name?":[":"[") + (o.length > 1 ? ("\n"+ind+"\t"+o.join(",\n"+ind+"\t")+"\n"+ind) : o.join("")) + "]";
}
else if (o == null)
json += (name&&":") + "null";
else if (typeof(o) == "object") {
var arr = [];
for (var m in o)
arr[arr.length] = X.toJson(o[m], m, ind+"\t");
json += (name?":{":"{") + (arr.length > 1 ? ("\n"+ind+"\t"+arr.join(",\n"+ind+"\t")+"\n"+ind) : arr.join("")) + "}";
}
else if (typeof(o) == "string")
json += (name&&":") + "\"" + o.toString() + "\"";
else
json += (name&&":") + o.toString();
return json;
},
innerXml: function(node) {
var s = ""
if ("innerHTML" in node)
s = node.innerHTML;
else {
var asXml = function(n) {
var s = "";
if (n.nodeType == 1) {
s += "<" + n.nodeName;
for (var i=0; i<n.attributes.length;i++)
s += " " + n.attributes[i].nodeName + "=\"" + (n.attributes[i].nodeValue||"").toString() + "\"";
if (n.firstChild) {
s += ">";
for (var c=n.firstChild; c; c=c.nextSibling)
s += asXml(c);
s += "</"+n.nodeName+">";
}
else
s += "/>";
}
else if (n.nodeType == 3)
s += n.nodeValue;
else if (n.nodeType == 4)
s += "<![CDATA[" + n.nodeValue + "]]>";
return s;
};
for (var c=node.firstChild; c; c=c.nextSibling)
s += asXml(c);
}
return s;
},
escape: function(txt) {
return txt.replace(/[\\]/g, "\\\\")
.replace(/[\"]/g, '\\"')
.replace(/[\n]/g, '\\n')
.replace(/[\r]/g, '\\r');
},
removeWhite: function(e) {
e.normalize();
for (var n = e.firstChild; n; ) {
if (n.nodeType == 3) { // text node
if (!n.nodeValue.match(/[^ \f\n\r\t\v]/)) { // pure whitespace text node
var nxt = n.nextSibling;
e.removeChild(n);
n = nxt;
}
else
n = n.nextSibling;
}
else if (n.nodeType == 1) { // element node
X.removeWhite(n);
n = n.nextSibling;
}
else // any other node
n = n.nextSibling;
}
return e;
}
};
if (xml.nodeType == 9) // document node
xml = xml.documentElement;
var json = X.toJson(X.toObj(X.removeWhite(xml)), xml.nodeName, "");
return "{" + (tab ? json.replace(/\t/g, tab) : json.replace(/\t|\n/g, "")) + "}";
}

View file

@ -29,7 +29,7 @@
');
}
// time zone
$time_zone = array(
'-1200' => '[GMT -12:00] Baker Island Time',
@ -90,7 +90,7 @@
* @return module controller instance
**/
function &getController($module_name) {
return getModule($module_name, 'controller');
return getModule($module_name, 'controller');
}
/**
@ -99,7 +99,7 @@
* @return module admin controller instance
**/
function &getAdminController($module_name) {
return getModule($module_name, 'controller','admin');
return getModule($module_name, 'controller','admin');
}
/**
@ -108,7 +108,7 @@
* @return module view instance
**/
function &getView($module_name) {
return getModule($module_name, 'view');
return getModule($module_name, 'view');
}
/**
@ -117,7 +117,7 @@
* @return module admin view instance
**/
function &getAdminView($module_name) {
return getModule($module_name, 'view','admin');
return getModule($module_name, 'view','admin');
}
/**
@ -126,7 +126,7 @@
* @return module model instance
**/
function &getModel($module_name) {
return getModule($module_name, 'model');
return getModule($module_name, 'model');
}
/**
@ -135,7 +135,7 @@
* @return module admin model instance
**/
function &getAdminModel($module_name) {
return getModule($module_name, 'model','admin');
return getModule($module_name, 'model','admin');
}
/**
@ -144,7 +144,7 @@
* @return module api class instance
**/
function &getAPI($module_name) {
return getModule($module_name, 'api');
return getModule($module_name, 'api');
}
/**
@ -153,7 +153,7 @@
* @return module class instance
**/
function &getClass($module_name) {
return getModule($module_name, 'class');
return getModule($module_name, 'class');
}
/**
@ -217,7 +217,7 @@
* @param tail 잘라졌을 경우 문자열의 제일 뒤에 붙을 꼬리
* @return string
**/
function cut_str($string,$cut_size=0,$tail = '...') {
function cut_str($string,$cut_size=0,$tail = '...') {
if($cut_size<1 || !$string) return $string;
$chars = Array(12, 4, 3, 5, 7, 7, 11, 8, 4, 5, 5, 6, 6, 4, 6, 4, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 4, 4, 8, 6, 8, 6, 10, 8, 8, 9, 8, 8, 7, 9, 8, 3, 6, 7, 7, 11, 8, 9, 8, 9, 8, 8, 7, 8, 8, 10, 8, 8, 8, 6, 11, 6, 6, 6, 4, 7, 7, 7, 7, 7, 3, 7, 7, 3, 3, 6, 3, 9, 7, 7, 7, 7, 4, 7, 3, 7, 6, 10, 6, 6, 7, 6, 6, 6, 9);
@ -389,7 +389,7 @@
return (float)$time1 + (float)$time2;
}
/**
/**
* @brief 첫번째 인자로 오는 object var에서 2번째 object의 var들을 제거
* @param target_obj object
* @param del_obj object의 vars에서 del_obj의 vars를 제거한다
@ -417,9 +417,9 @@
return $return_obj;
}
/**
/**
* @brief php5 이상에서 error_handing을 debugPrint로 변경
* @param errno
* @param errno
* @param errstr
* @return file
* @return line
@ -537,7 +537,7 @@
'green' => 0xFF & ($int >> 0x8),
'blue' => 0xFF & $int);
}
}
/**
@ -577,9 +577,9 @@
return $url;
}
/**
/**
* javascript의 escape의 php unescape 함수
* Function converts an Javascript escaped string back into a string with specified charset (default is UTF-8).
* Function converts an Javascript escaped string back into a string with specified charset (default is UTF-8).
* Modified function from http://pure-essence.net/stuff/code/utf8RawUrlDecode.phps
**/
function utf8RawUrlDecode ($source) {
@ -620,4 +620,38 @@
if($num<2097152)return chr(($num>>18)+240).chr((($num>>12)&63)+128).chr((($num>>6)&63)+128) .chr(($num&63)+128);
return '';
}
function json_encode2($data) {
switch (gettype($data)) {
case 'boolean':
return $data?'true':'false';
case 'integer':
case 'double':
return $data;
case 'string':
return '"'.strtr($data, array('\\'=>'\\\\','"'=>'\\"')).'"';
case 'object':
$data = get_object_vars($data);
case 'array':
$rel = false; // relative array?
$key = array_keys($data);
foreach ($key as $v) {
if (!is_int($v)) {
$rel = true;
break;
}
}
$arr = array();
foreach ($data as $k=>$v) {
$arr[] = ($rel?'"'.strtr($k, array('\\'=>'\\\\','"'=>'\\"')).'":':'').json_encode2($v);
}
return $rel?'{'.join(',', $arr).'}':'['.join(',', $arr).']';
default:
return '""';
}
}
?>