<?php
/**
 * api 基类
 * @package
 * @version 1.0:
 * @copyright 2003-2009 ShopEx
 * @author dreamdream
 * @license Commercial
 */
class shop_api_object{
    var $data_format='xml';//返回值类型 默认字符返回 0,1 返回 xml,2 返回 json
    var $version='1.0';
    var $columns_split='|';//字段默认分格
    var $select_limited=20;//获取记录的上线
    var $model_instance;
    var $gzip;
    var $application_error=array();
    /**
    * 构造函数
    */
    function shop_api_object(){
        if(!$this->system){
            $this->system = &$GLOBALS['system'];
        }
        if(!$this->db){
            $this->db = $this->system->database();
        }
    }
    /**
    * API 内部调用方法
    * @param string link的方法名称
    * @param string api的版本
    * @return api方法实例
    */

    function load_api_instance($act,$api_version){
        if(!$this->method){
            $this->method=include(CORE_DIR.'/api/include/api_link.php');
        }
        $callmethod=$this->method[$act][$api_version];
        if($ctl=$callmethod['ctl']){
            if(!$this->model_instance[$ctl]){
                include_once(CORE_DIR.'/'.dirname($ctl).'/'.$api_version.'/'.basename($ctl).'.php');
                $ctl=basename($ctl);
                $this->model_instance[$ctl]=new $ctl;
                $this->model_instance[$ctl]->data_format=$this->data_format;
            }
            return $this->model_instance[$ctl];
        }
    }

    /**
    * 数据返回
    * @param array 数据源
    * @author DreamDream
    * @return 将数据按照设定的类型返回
    */

    function return_date($data){
        switch($this->data_format){
            case 'string':
                $result=print_r($data,true);
            break;
            case 'json':
                $this->_header('text/html');
                // 对uf8编号进行unicode处理 b2b 2010-02-26 18:34 wubin
                $data = function_exists('ucs_encode')? ucs_encode($data) : $data;
                $result= json_encode($data);
            break;
            case 'xml':
                $this->_header('text/xml');
                $xml=&$this->system->loadModel('utility/xml');
                $result= $xml->array2xml($data,'shopex');

            break;
            case 3:

            break;
            case 'soap':

                //soap
            break;
            default:
                 $this->api_response('fail','language error',$data);
            break;

        }
        if($this->gzip && function_exists('gzencode')){
            echo @gzencode($result);
        }else{
            echo $result;
        }
        exit();
    }


    function varify_date_whole(&$data){
        $aData=$this->getColumns();
        foreach($data as $key=>$v){
            if($aData[$key]){
                $result[$key]=$v;
                unset($data[$key]);
            }
        }
        if($data){
            $this->api_response('fail','data fail',$data);
        }
        return $result;
    }

    /**
    * 头文件
    * @param string 文件类型
    * @param string 编码格式
    * @author DreamDream
    */
    function _header($content='text/html',$charset='utf-8'){
        header('Content-type: '.$content.';charset='.$charset);
        if($this->gzip && function_exists('gzencode')){
            header('Content-Encoding: gzip');
        }
        header("Cache-Control: no-cache,no-store , must-revalidate");
        $expires = gmdate ("D, d M Y H:i:s", time() + 20);
        header("Expires: " .$expires. " GMT");
    }


    /**
    * API LOG
    * @param log的信息
    * @param 原始文件
    * @author DreamDream
    */
    function api_error_log($msg,$data){
        $path=HOME_DIR.'/logs';
        $handle=fopen($path.'/'.date("Ymd").'.log','a+');
        $content='data:'.date("Y m d H:i:s").print_r($data,true)."\r\n";
        fwrite($content);
        fclose($handle);
    }

    /**
    * 通用过滤器
    * @param 查询条件
    * @param 过滤器原值
    * @author DreamDream
    * @return 过滤过的筛选条件
    */
    function _filter($where=array(1),$filter){
        $filter['pages']=$filter['pages']?intval($filter['pages']):1;
        $filter['counts']=$filter['counts']?intval($filter['counts']):$this->select_limited;
        if($filter['counts']>$this->select_limited){
           $filter['counts']=$this->select_limited;
        }
        $limit=' limit '.intval($filter['pages']-1)*$filter['counts'].','.$filter['counts'];
        if(count($where) > 1){
            $result=' where '.implode($where,' and ');
        }else{
            $result=' where '.$where[0];
        }
        if($filter['orderby']){
            $result.=' order by '.$filter['orderby'];
        }
        $result .= $limit;
        if(trim($result)=='where limit 0,100'){
            $result = $limit;
        }
        return $result;
    }

    function load_model($path,$apiversion='1.0'){
        $file=API_DIR.'/'.dirname($path).'/'.$apiversion.'/model/mdl.'.basename($path).'.php';
        if(file_exists($file)){
            require_once($file);
            $mdl_instalce='mdl_'.basename($path);
            if(!$this->model[$path]){
                $this->model[$path]=new $mdl_instalce;
            }else{
                return $this->model[$path];
            }
        }

    }
    /**
    * 数据校验
    * @param 原数据值
    * @param 必备的数据字段
    * @author DreamDream
    * @return 是否是正确数据
    */
    function verify_data(&$data,&$key_value){
        if($key_value['required']){
            foreach($key_value['required'] as $value){
                if(!isset($data[$value])){
                    $this->api_response('fail','data fail');
                }
            }
        }
        if($key_value['columns']){
            if($data['columns']){
                $data['columns']=explode('|',$data['columns']);
                $_tmpcolumns="";
                $columns=$this->getColumns();
                foreach($data['columns'] as $key=>$v){
                    if($columns[$v]){
                        if($columns[$v]['join']){
                            $data['columns_join'][$v]=true;
                            unset($data['columns'][$key]);
                        }
                        if($columns[$v]['name']){
                            $data['columns'][$key]=$columns[$v]['name'].' as '.$v;
                        }
                    }
                }
            }else{
                if(method_exists($this,'getColumns')){
                    foreach((array)$this->getColumns() as $key=>$v){
                        if($v['join']){
                            $data['columns_join'][$key]=true;
                        }else if($v['name']){
                            $data['columns'][]=$v['name'].' as '.$key;
                        }else{
                            $data['columns'][]=$key;
                        }
                    }
                }
            }
            if(is_array($key_value['columns'])){
                foreach($key_value['columns'] as $value){
                    if(!in_array($value,$data['columns'])){
                        $this->api_response('fail','data fail');
                    }
                }
            }
        }
        return true;
    }
    /*
    function application_error_handle($code,$debug,$info,$desc){
        if($debug){
            $this->app_error[$code]['debug']=$debug;
        }
        if($info){
            $this->app_error[$code]['info']=$info;
        }
        if($desc){
            $this->app_error[$code]['desc']=$desc;
        }
        return $this->app_error[$code];
    }
    */

    /**
    * API 添加应用级错误
    * @param 错误码
    * @param 调试错误信息，放数据源
    * @param 错误信息
    * @param 错误详细说明
    * @author DreamDream
    * @return 成功数据信息，失败错误信息
    */

    function add_application_error($code,$debug,$info,$desc){
        if($debug){
            $this->app_error[$code]['debug']=$debug;
        }
        if($info){
            $this->app_error[$code]['info']=$info;
        }
        if($desc){
            $this->app_error[$code]['desc']=$desc;
        }
        if($this->app_error[$code]){
            $this->application_error[]=$this->app_error[$code];
            if($this->app_error[$code]['level']=='error'){
               $this->api_response('fail','data fail',null,'application error');
            }
        }

    }
    function api_erro_table($code){
        return $error($code);
    }

    /**
    * API 返回值
    * @param 返回码
    * @param 是否发生错误
    * @param 数据原始值
    * @author DreamDream
    * @return 成功数据信息，失败错误信息
    */

    function api_response($resCode,$errorCode=false,$data=null,$info=null){
        $resposilbe=array(
            'true'=>'success',
            'fail'=>'fail',
            'wait'=>'wait'
        );
        if($errorCode){
            $error=$this->error_code($errorCode);
            if(constant('API_ERROR_LOG')){
                if(constant('API_ERROR_LOG_LEVEL')){
                    if($error['level']>=API_ERROR_LOG_LEVEL){
                        $this->api_error_log($error,$data);
                    }
                }else{
                    $this->api_error_log($error,$data);
                }
            }
            $result['result']=$resposilbe[$resCode];
            $result['msg']=$error['code'];
            $result['info']=$info?$info:$errorCode;
        }else{
            foreach($data['data_info'] as $key=>$value){
                if(!$data['data_info'][$key] && $data['data_info'][$key]!=='0' && $data['data_info'][$key]!==0){
                   $data['data_info'][$key]='';
                }
            }
            $result['result']=$resposilbe[$resCode];
            $result['msg']='';
            $result['info']=$data;

        }
        if($this->application_error&&is_array($this->application_error)){
            $result['application_error']=$this->application_error;
        }
        echo $this->return_date($result);
        exit();
    }


    /**
    * API 错误码
    * @param 错误编码
    * @author DreamDream
    * @return 返回错误信息
    */
    function &error_code($code){
        if($this->error){
            $this->error=include('include/api_error_handle.php');
        }
        return $this->error[$code];
    }
}
?>