| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577 | <?php namespace Upload\Lib;use Dever;class Save{    private $config;    private $ext = array    (        1 => 'jpg,png,gif,webp,jpeg',        2 => 'mp3,m4a' ,        3 => 'video,flv,mp4,webm,mov',        4 => 'doc,xls,xlsx,docx',        5 => 'pdf',        6 => 'rar,zip',        7 => 'cer,pfx,pem',        8 => 'exe,msi',    );    private $type = 1;    public function init($id, $cate_id = 1, $group_id = false, $user_id = false)    {        $this->config = Dever::db('rule', 'upload')->find($id);        if (!$this->config) {            Dever::error('上传规则错误');        }        $this->config['save'] = Dever::db('save', 'upload')->find($this->config['save_id']);        if (!$this->config['save']) {            Dever::error('存储位置错误');        }        $this->cate_id = $cate_id ? $cate_id : 1;        $this->group_id = $group_id;        $this->user_id = $user_id;        return $this;    }    public function get($id)    {        $this->init($id);        $result = array();        $result['id'] = $id;        $result['chunkSize'] = $this->config['chunk'];        $result['path'] = $id;        $result['size'] = $this->config['size'];        $result['accept'] = '';        $result['mine'] = array();        $mine = $this->getExtByMine(false, true);        $type = explode(',', $this->config['type']);        foreach ($type as $v) {            if (isset($this->ext[$v])) {                $result['accept'] .= '.' . str_replace(',', ',.', $this->ext[$v]);                $temp = explode(',', $this->ext[$v]);                foreach ($temp as $v2) {                    if (isset($mine[$v2])) {                        $result['mine'][] = $mine[$v2];                    }                }            }        }        $result['type'] = $this->config['save']['type'];        $result['method'] = $this->config['save']['method'];        if ($result['type'] > 1) {            $result += Dever::load('tool', 'upload')->get($this->config['save'])->getInfo();        }        return $result;    }    public function act($source, $default_ext = '', $uid = false, $dest_name = '')    {        if (!$this->config) {            Dever::error('上传规则错误');        }        $name = '';        $ext = '';        $size = 0;        $method = '';        $source_name = '';        $chunk = array();        if (is_array($source) && isset($source['tmp_name'])) {            # 文件上传            $type = 1;            if ($source['name'] == 'blob' && $source['type'] == 'application/octet-stream') {                $source['name'] = Dever::input('name');                $source['type'] = Dever::input('type');            }            $total = Dever::input('chunks');            if ($total > 1) {                $chunk['size'] = $this->config['chunk'];                $chunk['uid'] = Dever::input('uid');                $chunk['timestamp'] = Dever::input('timestamp');                $chunk['cur'] = Dever::input('chunk');                $chunk['total'] = $total;                if (!$chunk['uid'] || !$chunk['timestamp'] || !$chunk['cur'] || !$chunk['total']) {                    Dever::error('分片配置信息无效');                }                $name = $source_name = $source['name'] . $chunk['timestamp'] . $chunk['uid'];            } else {                $source_name = $source['name'];                //$name = $source_name . uniqid(date('YmdHis'), true) . mt_rand(10000, 99999);                $name = $source_name . $source['type'] . $source['size'];            }                        $ext = $this->getExtByMine($source['type']);            $size = $source['size'];            $method = 'getimagesize';            $source = $source['tmp_name'];        } elseif (is_string($source)) {            if (strstr($source, ';base64,')) {                # base64编码                $temp = explode(';base64,', $source);                $ext = $this->getExtByMine(ltrim($temp[0], 'data:'));                $source = str_replace(' ', '+', $temp[1]);                $source = str_replace('=', '', $temp[1]);                $source = base64_decode($source);                $size = strlen($source);                $size = round(($size - ($size/8)*2)/1024, 2);                $method = 'getimagesizefromstring';                $type = 2;            } else {                if (strstr($source, 'http'))  {                    # http远程文件                    $name = $source;                    $type = 3;                    $ext = pathinfo($source, PATHINFO_EXTENSION);                    if ($this->config['save']['type'] == 1) {                        $content = Dever::curl($source)->log(false)->result();                        $source = Dever::file('tmp/' . sha1($name));                        file_put_contents($source, $content);                    }                }                if (is_file($source)) {                    # 本地文件                    $type = 1;                    $name = $source;                    $finfo = finfo_open(FILEINFO_MIME);                    $code = finfo_file($finfo, $source);                    finfo_close($finfo);                    $temp = explode(';', $code);                    $ext = $this->getExtByMine($temp[0]);                    $size = filesize($source);                    $method = 'getimagesize';                }            }        } else {            $source = false;        }        if (!$source) {            Dever::error('源文件不存在');        }        if (!$ext) {            $ext = $this->getExtByByte($source);        }        if (!$ext && $default_ext) {            $ext = $default_ext;        }        $state = $this->check($ext, $size, $method, $source);        if (is_string($state)) {            if (isset($content)) {                @unlink($source);            }            Dever::error($state);        }        if ($dest_name) {            $name = $dest_name;        }        $dest = $this->config['id'] . '/' . $this->getDest($name, $ext, $uid);        # type 1是文件复制 2是base64 3是远程文件复制        $url = Dever::load('tool', 'upload')->get($this->config['save'])->upload($type, $source, $dest, $chunk, $this);        $data = $this->up($source_name, $name, $dest, $this->config['size'], $this->config['width'] ?? 0, $this->config['height'] ?? 0);        $data['url'] = $url;        $data['type'] = $this->type;        if (isset($content)) {            @unlink($source);        }        return $data;    }    public function addFile($url, $source_name, $name, $dest, $size)    {        if ($this->config['save']['type'] > 1) {            $url = Dever::load('tool', 'upload')->get($this->config['save'])->getUrl(3, $url, $this);            if (isset($this->config['size']) && $this->config['size']) {                $size = $this->config['size'];            }        }                $data = $this->up($source_name, $name, $dest, $size, $this->config['width'] ?? 0, $this->config['height'] ?? 0);        $data['url'] = $url;        return $data;    }    private function up($source_name, $name, $dest, $size, $width = 0, $height = 0)    {        $file['rule_id'] = $this->config['id'];        $file['name'] = $name;        $data = $file;        $data['source_name'] = $source_name;        $data['file'] = $dest;        $data['save_id'] = $this->config['save_id'];        $data['size'] = $size;        if ($width) {            $data['width'] = $width;        }        if ($height) {            $data['height'] = $height;        }        $data['cate_id'] = $this->cate_id;        $data['group_id'] = $this->group_id;        $data['user_id'] = $this->user_id;        $data['id'] = Dever::db('file', 'upload')->up($file, $data);        return $data;    }    public function after()    {        $data = Dever::db('rule_after', 'upload')->select(array('rule_id' => $this->config['id']));        if ($data) {            foreach ($data as $k => $v) {                $table = '';                if ($v['type'] == 1) {                    $table = 'thumb';                } elseif ($v['type'] == 2) {                    $table = 'crop';                } elseif ($v['type'] == 3) {                    $table = 'water_pic';                } elseif ($v['type'] == 4) {                    $table = 'water_txt';                }                if ($table && $v['type_id']) {                    $data[$k]['table'] = $table;                    $data[$k]['param'] = Dever::db($table, 'image')->find($v['type_id']);                }            }        }        return $data;    }    public function check($ext, $size, $info, $source = '')    {        $result = $this->checkExt($ext);        if (is_string($result)) {            return $result;        }        if ($size) {            $result = $this->checkSize($size);            if (is_string($result)) {                return $result;            }            if ($this->type == 1 && $info) {                if (is_string($info)) {                    $info = $info($source);                }                if ($info) {                    $result = $this->checkLimit($info);                    if (is_string($result)) {                        return $result;                    }                }            }        }        return true;    }    protected function checkExt($ext)    {        $this->type = 0;        if (!$ext) {            return '文件格式错误';        }        $state = false;        $type = explode(',', $this->config['type']);        foreach ($type as $v) {            if (isset($this->ext[$v]) && strstr($this->ext[$v], $ext)) {                $this->type = $v;                $state = true;                break;            }        }        if (!$state) {            return '文件格式不符合要求';        }        $this->config['ext'] = $ext;        return true;    }    protected function checkSize($size)    {        $set = $this->config['size'];        if (!$set) {            $set = 2;        }        $limit = $set * 1048576;        if ($size > $limit) {            return '文件不能超过'.$set.'MB';        }        $this->config['size'] = $size;    }    protected function checkLimit($info)    {        if (isset($this->config['limit']) && $this->config['limit'] == 2 && $info[0] < $info[1]) {            return '文件高度不能超过文件宽度';        } elseif (isset($this->config['limit']) &&  $this->config['limit'] == 3 && $info[0] > $info[1]) {            return '文件宽度不能超过文件高度';        } elseif ($this->config['min_width'] > 0 && $this->config['min_width'] > $info[0]) {            return '文件宽度不能小于' . $this->config['min_width'] . 'px';        } elseif ($this->config['min_height'] > 0 && $this->config['min_height'] > $info[1]) {            return '文件高度不能小于' . $this->config['min_height'] . 'px';        }        $this->config['width'] = $info[0];        $this->config['height'] = $info[1];    }    protected function getDest(&$name, $ext, $uid)    {        if ($uid) {            $id = abs(intval($uid));            $id = sprintf("%09d", $id);            $dest = DIRECTORY_SEPARATOR . substr($id, 0, 3) . DIRECTORY_SEPARATOR . substr($id, 3, 2) . DIRECTORY_SEPARATOR . substr($id, 5, 2) . DIRECTORY_SEPARATOR . $uid . '.' . $ext;            $name = $uid;        } else {            if (!strpos($name, '_cr_')) {                $name = md5($name);            }            $path = array_slice(str_split($name, 2), 0, 3);            $dest = implode(DIRECTORY_SEPARATOR, $path) . DIRECTORY_SEPARATOR . $name . '.' . $ext;        }        return $dest;    }    protected function getExtByMine($mine, $flip = false, $result = false)    {        if (!$mine) {            return '';        }        $config = array        (            'application/envoy' => 'evy',            'application/fractals' => 'fif',            'application/futuresplash' => 'spl',            'application/hta' => 'hta',            'application/internet-property-stream' => 'acx',            'application/mac-binhex40' => 'hqx',            'application/msword' => 'doc',            'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' => 'xlsx',            'application/vnd.openxmlformats-officedocument.wordprocessingml.document' => 'docx',            'video/x-m4v' => 'mp4',            'video/mp4' => 'mp4',            'application/octet-stream' => 'exe',            'application/oda' => 'oda',            'application/olescript' => 'axs',            'application/pdf' => 'pdf',            'application/pics-rules' => 'prf',            'application/pkcs10' => 'p10',            'application/pkix-crl' => 'crl',            'application/postscript' => 'ai',            'application/postscript' => 'eps',            'application/postscript' => 'ps',            'application/rtf' => 'rtf',            'application/set-payment-initiation' => 'setpay',            'application/set-registration-initiation' => 'setreg',            'application/vnd.ms-excel' => 'xls',            'application/vnd.ms-outlook' => 'msg',            'application/vnd.ms-pkicertstore' => 'sst',            'application/vnd.ms-pkiseccat' => 'cat',            'application/vnd.ms-pkistl' => 'stl',            'application/vnd.ms-powerpoint' => 'ppt',            'application/vnd.ms-project' => 'mpp',            'application/vnd.ms-works' => 'wps',            'application/winhlp' => 'hlp',            'application/x-bcpio' => 'bcpio',            'application/x-cdf' => 'cdf',            'application/x-compress' => 'z',            'application/x-compressed' => 'tgz',            'application/x-cpio' => 'cpio',            'application/x-csh' => 'csh',            'application/x-director' => 'dir',            'application/x-dvi' => 'dvi',            'application/x-gtar' => 'gtar',            'application/x-gzip' => 'gz',            'application/x-hdf' => 'hdf',            'application/x-internet-signup' => 'isp',            'application/x-iphone' => 'iii',            'application/x-javascript' => 'js',            'application/x-latex' => 'latex',            'application/x-msaccess' => 'mdb',            'application/x-mscardfile' => 'crd',            'application/x-msclip' => 'clp',            'application/x-msdownload' => 'dll',            'application/x-msmediaview' => 'mvb',            'application/x-msmetafile' => 'wmf',            'application/x-msmoney' => 'mny',            'application/x-mspublisher' => 'pub',            'application/x-msschedule' => 'scd',            'application/x-msterminal' => 'trm',            'application/x-mswrite' => 'wri',            'application/x-netcdf' => 'cdf',            'application/x-netcdf' => 'nc',            'application/x-perfmon' => 'pma',            'application/x-pkcs12' => 'p12',            'application/x-pkcs12' => 'pfx',            'application/x-pkcs7-certificates' => 'p7b',            'application/x-pkcs7-certreqresp' => 'p7r',            'application/x-pkcs7-mime' => 'p7c',            'application/x-pkcs7-signature' => 'p7s',            'application/x-sh' => 'sh',            'application/x-shar' => 'shar',            'application/x-shockwave-flash' => 'swf',            'application/x-stuffit' => 'sit',            'application/x-sv4cpio' => 'sv4cpio',            'application/x-sv4crc' => 'sv4crc',            'application/x-tar' => 'tar',            'application/x-tcl' => 'tcl',            'application/x-tex' => 'tex',            'application/x-texinfo' => 'texi',            'application/x-texinfo' => 'texinfo',            'application/x-troff' => 'roff',            'application/x-troff' => 't',            'application/x-troff' => 'tr',            'application/x-troff-man' => 'man',            'application/x-troff-me' => 'me',            'application/x-troff-ms' => 'ms',            'application/x-ustar' => 'ustar',            'application/x-wais-source' => 'src',            'application/x-x509-ca-cert' => 'cer',            'application/ynd.ms-pkipko' => 'pko',            'application/zip' => 'zip',            'audio/basic' => 'au',            'audio/basic' => 'snd',            'audio/mid' => 'mid',            'audio/mid' => 'rmi',            'audio/mpeg' => 'mp3',            'audio/mp3' => 'mp3',            'audio/x-aiff' => 'aif',            'audio/x-aiff' => 'aifc',            'audio/x-aiff' => 'aiff',            'audio/x-mpegurl' => 'm3u',            'audio/x-pn-realaudio' => 'ram',            'audio/x-wav' => 'wav',            'image/png' => 'png',            'image/bmp' => 'bmp',            'image/cis-cod' => 'cod',            'image/gif' => 'gif',            'image/ief' => 'ief',            'image/jpeg' => 'jpg',            'image/pipeg' => 'jfif',            'image/svg+xml' => 'svg',            'image/tiff' => 'tif',            'image/tiff' => 'tiff',            'image/x-cmu-raster' => 'ras',            'image/x-cmx' => 'cmx',            'image/x-icon' => 'ico',            'image/x-portable-anymap' => 'pnm',            'image/x-portable-bitmap' => 'pbm',            'image/x-portable-graymap' => 'pgm',            'image/x-portable-pixmap' => 'ppm',            'image/x-rgb' => 'rgb',            'image/x-xbitmap' => 'xbm',            'image/x-xpixmap' => 'xpm',            'image/x-xwindowdump' => 'xwd',            'message/rfc822' => 'mht',            'message/rfc822' => 'mhtml',            'message/rfc822' => 'nws',            'text/css' => 'css',            'text/h323' => '323',            'text/html' => 'html',            'text/iuls' => 'uls',            'text/plain' => 'txt',            'text/richtext' => 'rtx',            'text/scriptlet' => 'sct',            'text/tab-separated-values' => 'tsv',            'text/webviewhtml' => 'htt',            'text/x-component' => 'htc',            'text/x-setext' => 'etx',            'text/x-vcard' => 'vcf',            'video/mpeg' => 'mpeg',            'video/quicktime' => 'mov',            'video/x-ms-asf' => 'asx',            'video/x-msvideo' => 'avi',            'video/x-sgi-movie' => 'movie',            'x-world/x-vrml' => 'flr',            'application/x-rar' => 'rar',            'application/vnd.android.package-archive' => 'apk',            'audio/webm' => 'webm',            'video/webm' => 'webm',            'audio/x-m4a' => 'm4a',            'image/webp' => 'webp',        );        if ($flip) {            $config = array_flip($config);        }        $mine = trim($mine);        if (isset($config[$mine])) {            return $config[$mine];        } else {            return false;        }    }    protected function getExtByByte($file)    {        $file = fopen($file, "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 8297:                $fileType = 'rar';                break;            case 255216:                $fileType = 'jpg';                break;            case 7173:                $fileType = 'gif';                break;            case 13780:                $fileType = 'png';                break;            case 6677:                $fileType = 'bmp';                break;            case 6787:                $fileType = 'swf';                break;            case 6063;                $fileType = 'php|xml';                break;            case 6033:                $fileType = 'html|htm|shtml';                break;            case 8075:                $fileType = 'zip';                break;            case 6782:            case 1310:                $fileType = 'txt';                break;            case 4742:                $fileType = 'js';                break;            case 8273:                $fileType = 'wav';                break;            case 7368:                $fileType = 'mp3';                break;            case 3780:                $fileType = 'pdf';                break;            case 4545:                $fileType = 'pem';                break;            case 7597:                $fileType = 'fbx';                break;            default:                $fileType = 'unknown'.$typeCode;            break;        }        if ($strInfo['chars1'] == '-1' && $strInfo['chars2'] == '-40') {            return 'jpg';        }        if ($strInfo['chars1'] == '-119' && $strInfo['chars2'] == '80') {            return 'png';        }        if ($strInfo['chars1'] == '-48' && $strInfo['chars2'] == '-49') {            return 'msi';        }        return $fileType;    }}
 |