<?php
/**
 * Reginx 上传类
 * @package include.lib 扩展库文件
 * @copyright reginx.com
 * $Id: upload.lib.php 22 2013-01-27 16:54:21Z reginx $
 */
class upload_lib{

    /**
     * 上传文件信息
     *
     * @var unknown_type
     */
    public $files = array();

    /**
     * 允许的文件类型,在配置文件里设置
     *
     * @var unknown_type
     */
    public $allowType  = NULL;

    /**
     * 允许文件大小
     *
     * @var unknown_type
     */
    public $maxSize  = NULL;

    /**
     * 文件保存根路径
     *
     * @var unknown_type
     */
    public $savePath = NULL;

    /**
     * 错误信息
     *
     * @var unknown_type
     */
    public $errs  = array();

    /**
     * 按日期生成的当前目录
     *
     * @var unknown_type
     */
    public $curDay = NULL;
    
    /**
     * 图片扩展
     *
     * @var unknown_type
     */
    public $image = array('jpg' , 'jpeg' , 'gif' , 'png' , 'bmp');

    /**
     * 构造函数
     *
     * @param unknown_type $allowType
     * @param unknown_type $saveDir
     * @param unknown_type $maxsize
     * @return upload_lib
     */
    public function upload_lib($allowType=null,$saveDir=NULL,$maxsize=NULL){
        $this->curDay    = date('Y-m-d',REQUEST_TIME);
        $this->savePath  = (empty($saveDir)   ? $GLOBALS['_APP']['data_path'] . 'attachment' : $saveDir);
        $this->allowType = (empty($allowType) ? $GLOBALS['_APP']['upload']['type'] : $allowType);
        $this->maxSize   = $this->getMaxFileSize(core::byteslen(empty($maxsize)?$GLOBALS['_APP']['upload']['max_size']:$maxsize));
        if(!preg_match('/^.*?\/$/i',$this->savePath)){ 
            $this->savePath .= '/'; 
        }
        if(!is_dir($this->savePath.$this->curDay)){
            mkdir($this->savePath.$this->curDay,0755) && file_put_contents($this->savePath.$this->curDay.'/index.html',' ');
        }
        if((int)$this->convert() === 0){ 
            $errs[] = core::L('no-files-input'); 
        }
    }

    /**
     * 获取文件
     *
     * @param unknown_type $key
     * @return unknown
     */
    public function getfile($key=NULL){
        $ret = array();
        if(!empty($key)){
            if(isset($this->files[$key])){
                if(isset($this->files[$key]['error'])){
                    $this->chk($this->files[$key]);
                    if((int)$this->files[$key]['error'] === 0){
                        $this->save($this->files[$key]);
                    }
                    $ret = $this->files[$key];
                }else{
                    foreach ($this->files[$key] as $v){
                        $this->chk($v);
                        if((int)$v['error'] === 0){
                            $this->save($v);
                        }
                        $ret[] = $v;
                    }
                }
            }
        }else{
            $this->save($this->files,1);
            $ret = $this->files;
        }
        return $ret;
    }

    /**
     * 文件检查
     *
     * @param unknown_type $file
     */
    public function chk(&$file){
        if((int)$file['error'] === 0){
            if(!$this->checkUpload($file['tmp_name'])){
                $file['error'] = core::L('lllegal-submitted');
            }else if($file['size'] > ($this->maxSize)){
                $file['error'] = core::L('size-error',$file['name'],intval($file["size"]/1024),intval(($this->maxSize)/1024));
            }else if(strrpos(strtolower($this->allowType),strtolower($file['ext'])) === false){
                $file['error'] = core::L('type-error',$file['ext']);
            }
        }else{
            if($file['error'] <= 2){
                $file['error'] = core::L('size-error',$file['name'],intval($file["size"]/1024),intval(($this->maxSize)/1024));
            }else if($file['error']==3){
                $file['error'] = core::L('partial-error');
            }else if($file['error']==4){
                $file['error'] = core::L('no-files-input');
            }else if($file['error']==6){
                $file['error'] = core::L('no-tmp-dir');
            }else if($file['error']==7){
                $file['error'] = core::L('cant-write');
            }
        }
    }

    /**
     * 保存文件
     *
     * @param unknown_type $file
     * @param unknown_type $isArray
     * @return unknown
     */
    public function save(&$file,$isArray=FALSE){
        if($isArray){
            foreach ($file as $k => $v){
                if(isset($v[0])){
                    foreach ($v as $subk => $subv){
                        if(!move_uploaded_file($subv["tmp_name"],$subv["savePath"].$subv["saveName"])){
                            $file[$k][$subk]['error'] = L('save-error');
                            core::error('Move File Fail: '.$subv['tmp_name'].' to '.$subv["savePath"].$subv["saveName"],'Upload',1);
                        }
                    }
                }else{
                    if(!move_uploaded_file($v["tmp_name"],$v["savePath"].$v["saveName"])){
                        $file[$k]['error'] = core::L('save-error');
                        core::error('Move File Fail: '.$v['tmp_name'].' to '.$v["savePath"].$v["saveName"],'Upload',1);
                    }
                }
            }
        }else if(!move_uploaded_file($file["tmp_name"],$file["savePath"].$file["saveName"])){
            core::error('Move File Fail: '.$file['tmp_name'].' to '.$file["savePath"].$file["saveName"],'Upload',1);
            return FALSE;
        }
        return TRUE;
    }

    /**
     * 上传数据整理
     *
     * @return Integer
     */
    public function convert() {
        $this->files = array();
        $tmp = $_FILES;
        if(empty($_FILES)){return 0;}
        foreach ($tmp as $k => $v){
            if($v['name'] != "" && !empty($v['name'])){
                if(is_array($v['error'])){
                    for ($i=0;$i<sizeof($v['error']);$i++){
                        $this->files[$k][$i]['size']      = $v['size'][$i];
                        $this->files[$k][$i]['error']     = $v['error'][$i];
                        $this->files[$k][$i]['ext']       = $this->getExt($v['tmp_name'][$i],$v['name'][$i]);
                        $this->files[$k][$i]['savePath']  = $this->savePath;
                        $this->files[$k][$i]['name']      = $v['name'][$i];
                        $this->files[$k][$i]['tmp_name']  = realpath($v['tmp_name'][$i]);
                        $this->files[$k][$i]['saveName']  = $this->curDay.'/'.$this->getSaveName($this->files[$k][$i]['ext']);
                        $this->files[$k][$i]['isimage']   = in_array(strtolower($this->files[$k][$i]['ext']) , $this->image);
                    }
                }else{
                    $this->files[$k]['size']     = $v['size'];
                    $this->files[$k]['error']    = $v['error'];
                    $this->files[$k]['ext']      = $this->getExt($v['tmp_name'],$v['name']);
                    $this->files[$k]['savePath'] = $this->savePath;
                    $this->files[$k]['name']     = $v['name'];
                    $this->files[$k]['tmp_name'] = realpath($v['tmp_name']);
                    $this->files[$k]['saveName'] = $this->curDay.'/'.$this->getSaveName($this->files[$k]['ext']);
                    $this->files[$k]['isimage']   = in_array(strtolower($this->files[$k]['ext']) , $this->image);
                }
            }
        }
        return 1;
    }

    /**
     * 生成文件名
     *
     * @param unknown_type $fext
     * @return unknown
     */
    public function getSaveName($ext){
        $pre = $GLOBALS['_APP']['upload']['att_pre'];
        return $pre ? $pre : 'pre_' . strtolower(core::randstr(12)) . ".".$ext;
    }

    /**
     * 获取文件扩展名
     *
     * @param unknown_type $filename
     * @param unknown_type $rpath
     * @return unknown
     */
    public function getExt($filename,$rpath){
        $s = pathinfo($rpath);
        if($s['extension']=='txt'){
            return $s['extension'];
        }
        if($s['extension']=='html'|$s['extension']=='htm'){
            return $s['extension'];
        }
        if(!file_exists($filename)){
            return "unkown";
        }
        $file = fopen($filename, "rb");
        $bin  = fread($file, 2);
        @fclose($file);
        $strInfo  = unpack("C2chars", $bin);
        $typeCode = intval($strInfo['chars1'].$strInfo['chars2']);
        $fileType = '';
        switch ($typeCode){
            case 7790:
                $fileType = 'exe';
                break;
            case 7784:
                $fileType = 'midi';
                break;
            case 8075:
                $fileType = 'zip';
                break;
            case 8297:
                $fileType = 'rar';
                break;
            case 255216:
                $fileType = 'jpg';
                break;
            case 7173:
                $fileType = 'gif';
                break;
            case 6677:
                $fileType = 'bmp';
                break;
            case 13780:
                $fileType = 'png';
                break;
            case 208194:
                $fileType = 'txt';
                break;
            default:
                $fileType = 'unknown';
        }
        return $fileType;

    }

    /**
     * 获取服务器支持的最大文件大小
     *
     * @param unknown_type $k
     * @return unknown
     */
    public function getMaxFileSize($k){
        if(function_exists('ini_get')){
            $max = min(core::byteslen(ini_get('memory_limit')),core::byteslen(ini_get('post_max_size')),core::byteslen(ini_get('upload_max_filesize')));
            if((int)$max === 0){
                $max = core::byteslen($GLOBALS['_APP']['upload']['max_size']);
            }
            return empty($k) ? $max : min($max,intval($k));
        }
        core::error(core::L('not-found','ini_get'),'Upload',1);
        return $k;
    }

    /**
     * 临时文件检查
     *
     * @param unknown_type $filename
     * @return unknown
     */
    public function checkUpload($filename){
        return is_uploaded_file($filename);
    }
}
?>