<?php
namespace imcat;

// Output
class basOut
{
    static 
$options = array(
        
// 输出参数-jsonp
        
'jsonp_callback' => 'callback',
        
'jsonp_return' => 'callback',
        
// 输出参数-xml
        
'root_node' => 'root', // 根节点名
        
'root_attr' => '', // 根节点属性
        
'item_node' => 'item', //数字索引的子节点名
        
'item_key'  => 'id', // 数字索引子节点key转换的属性名
        
'encoding'  => 'utf-8', // 数据编码
    
);

    static 
$contentType = ''; // application/json, application/javascript, text/xml

    // 格式化输出
    
static function fmt($data, $type='json')
    {
        
$type = in_array($type,array('jsonp','xml')) ? $type : 'json';
        
$method = 'out'.ucfirst($type);
        
$re = self::$method($data);
        return 
$re;
    }

    static function 
outJson($data)
    {
        try {
            
// 返回JSON数据格式到客户端 包含状态信息
            
$data = comParse::jsonEncode($data);
            return 
$data;
        } catch (
Exception $e) {
            if (
$e->getPrevious()) {
                throw 
$e->getPrevious();
            }
            throw 
$e;
        }
    }

    static function 
outJsonp($data)
    {
        
$opt = self::$options;
        try {
            
// 返回JSON数据格式到客户端
            
$callback = basReq::val('callback',$opt['jsonp_callback']); 
            
$handler = !empty($callback) ? $callback : $opt['jsonp_return'];
            
$data = comParse::jsonEncode($data);
            
$data = $handler . '(' . $data . ');';
            return 
$data;
        } catch (
Exception $e) {
            if (
$e->getPrevious()) {
                throw 
$e->getPrevious();
            }
            throw 
$e;
        }
    }

    static function 
outXml($data, $uopt=array())
    {
        
$opt = self::$options;
        if(!empty(
$uopt)) $opt = array($opt, $uopt);
        
$attr = $opt['root_attr'];
        if(
is_array($attr)) {
            
$arr = array();
            foreach (
$attr as $key => $value) {
                
$arr[] = "{$key}=\"{$value}\"";
            }
            
$attr = implode(' ', $arr);
        }
        
$attr = trim($attr);
        
$attr = empty($attr) ? '' : " {$attr}";
        
$xml  = "<?xml version=\"1.0\" encoding=\"{$opt['encoding']}\"?>\n";
        
$xml .= "<{$opt['root_node']}{$attr}>\n";
        
$xml .= self::xmlRow($data, $opt['item_node'], $opt['item_key']);
        
$xml .= "</{$opt['root_node']}>\n";
        return 
$xml;
    }

    
/**
     * 数据XML编码
     * @param mixed  $data 数据
     * @param string $item 数字索引时的节点名称
     * @param string $id   数字索引key转换为的属性名
     * @return string
     */
    
static function xmlRow($data, $item, $id)
    {
        
$xml = $attr = '';
        
$a1 = array("&", "<", ">");
        
$a2 = array("&amp;", "&lt;", "&gt;");
        foreach (
$data as $key => $val) {
            if (
is_numeric($key)) {
                
$id && $attr = " {$id}=\"{$key}\"";
                
$key         = $item;
            }
            
$val = (is_array($val)||is_object($val)) ? self::xmlRow($val,$item,$id) : str_replace($a1,$a2,$val);
            
$xml .= "<{$key}{$attr}>$val</{$key}>\n";
        }
        return 
$xml;
    }
}

/*
$res = array(
    'errno' => 0,
    'state' => 'success',
    'msg' => 'msg',
    'data' => array(
        'uid' => 1234,
        'uname' => 'peace',
    ),
);
*/