_root = $arr['root']; $this->_rootname = $arr['name']; //$this->perm = perm_binPerm::getMyPower(); //self::init($path); } /* * 初始化qcos 返回 qcos对象实例 */ public function init($bz, $isguest = 1) { global $_G; $bzarr = explode(':', $bz); $id = trim($bzarr[1]); if (!$root = DB::fetch_first("select * from " . DB::table(self::T) . " where id='{$id}'")) { return array('error' => 'need authorize to ' . $bzarr[0]); } if (!$isguest && $root['uid'] > 0 && $root['uid'] != $_G['uid']) return array('error' => 'need authorize to qcos'); //$access_id = authcode($root['access_id'], 'DECODE', $root['bz']); $access_id = dzzdecode($root['access_id'], $root['bz']); if (empty($access_id)) $access_id = $root['access_id']; //$access_key = authcode($root['access_key'], 'DECODE', $root['bz']); $access_key = dzzdecode($root['access_key'], $root['bz']); $this->bucket = $root['bucket']; $hostnamearr = explode(':', $root['hostname']); $schema = isset($hostnamearr[0]) ? $hostnamearr[0] : 'http'; $region = isset($hostnamearr[1]) ? $hostnamearr[1] : 'ap-beijing'; try { $this->qcos_config = [ 'credentials' => array( 'secretId' => $access_id, 'secretKey' => $access_key ), 'region' => $region, 'schema' => $schema, ]; $this->host = $root['host']; $qcos = new Qcloud\Cos\Client($this->qcos_config); return $qcos; } catch (Exception $e) { return array('error' => $e->getMessage()); } } public function get_authorization($secretKey,$secretId,$StartTimestamp, $EndTimestamp, $fileUri, $headers, $method = 'get') { $qSignTime = "$StartTimestamp;$EndTimestamp"; $qKeyTime = $qSignTime; $header_list = $this->get_q_header_list($headers); //如果 Uri 中带有 ?的请求参数,该处为数组排序后的字符串组合 $url_param_list = ''; $httpMethod = $method; $httpUri = $fileUri; //与 q-url-param-list 相同 $httpParameters = $url_param_list; //将自定义请求头分解为 & 连接的字符串 $headerString = $this->get_http_header_string($headers); // 计算签名中的 signature 部分 $signTime = $qSignTime; $signKey = hash_hmac('sha1', $signTime, $secretKey); $httpString = "$httpMethod\n$httpUri\n$httpParameters\n$headerString\n"; $sha1edHttpString = sha1($httpString); $stringToSign = "sha1\n$signTime\n$sha1edHttpString\n"; $signature = hash_hmac('sha1', $stringToSign, $signKey); //组合结果 $authorization = "q-sign-algorithm=sha1&q-ak=$secretId&q-sign-time=$qSignTime&q-key-time=$qKeyTime&q-header-list=$header_list&q-url-param-list=$url_param_list&q-signature=$signature"; return $authorization; } //组合header数据 public function get_q_header_list($headers) { if (!is_array($headers)) { return false; } try { $tmpArray = array(); foreach ($headers as $key => $value) { array_push($tmpArray, strtolower($key)); } sort($tmpArray); return implode(';', $tmpArray); } catch (Exception $error) { return false; } } //获取header字符串 public function get_http_header_string($headers) { if (!is_array($headers)) { return false; } try { $tmpArray = array(); foreach ($headers as $key => $value) { $tmpKey = strtolower($key); $tmpArray[$tmpKey] = urlencode($value); } ksort($tmpArray); $headerArray = array(); foreach ($tmpArray as $key => $value) { array_push($headerArray, "$key=$value"); } return implode('&', $headerArray); } catch (Exception $error) { return false; } } public function getAuthorization($secretid, $secretkey, $filename,$method='get') { // 获取个人 API 密钥 https://console.qcloud.com/capi $SecretId = $secretid; $SecretKey = $secretkey; // 整理参数 $queryParams = array(); $headers = array(); $method = strtolower($method ? $method : 'head'); $filename = $filename ? $filename : '/'; substr($filename, 0, 1) != '/' && ($filename = '/' . $filename); // 要用到的 Authorization 参数列表 $qSignAlgorithm = 'sha1'; $qAk = $SecretId; $qSignTime = (string)(time() - 60) . ';' . (string)(time() + 3600); $qKeyTime = $qSignTime; $qHeaderList = strtolower(implode(';', $this->getObjectKeys($headers))); $qUrlParamList = strtolower(implode(';', $this->getObjectKeys($queryParams))); // 签名算法说明文档:https://www.qcloud.com/document/product/436/7778 // 步骤一:计算 SignKey $signKey = hash_hmac("sha1", $qKeyTime, $SecretKey); // 步骤二:构成 FormatString $formatString = implode("\n", array(strtolower($method), $filename, $this->obj2str($queryParams), $this->obj2str($headers), '')); // 步骤三:计算 StringToSign $stringToSign = implode("\n", array('sha1', $qSignTime, sha1($formatString), '')); // 步骤四:计算 Signature $qSignature = hash_hmac('sha1', $stringToSign, $signKey); // 步骤五:构造 Authorization $authorization = implode('&', array( 'q-sign-algorithm=' . $qSignAlgorithm, 'q-ak=' . $qAk, 'q-sign-time=' . $qSignTime, 'q-key-time=' . $qKeyTime, 'q-header-list=' . $qHeaderList, 'q-url-param-list=' . $qUrlParamList, 'q-signature=' . $qSignature )); return $authorization; } // 工具方法 public function getObjectKeys($obj) { $list = array_keys($obj); sort($list); return $list; } public function obj2str($obj) { $list = array(); $keyList = $this->getObjectKeys($obj); $len = count($keyList); for ($i = 0; $i < $len; $i++) { $key = $keyList[$i]; $val = isset($obj[$key]) ? $obj[$key] : ''; $key = strtolower($key); $list[] = rawurlencode($key) . '=' . rawurlencode($val); } return implode('&', $list); } public function getapidatas($bucket,$region,$url, $params, $authheader, $xmldata = '') { $arr_header[] = "Content-Type:application/xml"; $arr_header[] = "Authorization: " . $authheader; $arr_header[] = "Host:".$bucket.".cos.".$region.".myqcloud.com"; //$arr_header[] = "x-cos-acl:private"; $ch = curl_init(); $url .= '?' . http_build_query($params); $url = str_replace('0=','',$url); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); if (!empty($arr_header)) { curl_setopt($ch, CURLOPT_HTTPHEADER, $arr_header); } if ($xmldata) { curl_setopt($ch, CURLOPT_POSTFIELDS, $xmldata); } curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_REFERER, ''); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); $response = curl_exec($ch); $xmlstring = simplexml_load_string($response, 'SimpleXMLElement', LIBXML_NOCDATA); curl_close($ch); $value_array = json_decode(json_encode($xmlstring), true); return $value_array; } //获取bucket读取权限 public function getAclPerm(){ $readperm = 1; $apparr = explode('-',$this->bucket); $appid = $apparr[1]; $bucket = $apparr[0]; $secret_id = $this->qcos_config['credentials']['secretId']; $secret_key = $this->qcos_config['credentials']['secretKey']; $aclpermcache = $this->bucket.'_readPerm'; if ($d = C::t('cache')->fetch_cachedata_by_cachename($aclpermcache,3600)) { return $d; }else { $StartTimestamp = time(); $EndTimestamp = $StartTimestamp + 3600; //请求地址 $queryurl = $this->bucket . '.cos.' . $this->qcos_config['region'] . '.myqcloud.com/'; $params = ['acl']; //请求头 $headers = []; $fileUri = '/'; $authorization = $this->get_authorization($secret_key,$secret_id,$StartTimestamp, $EndTimestamp, $fileUri, $headers); $data = $this->getapidatas($this->bucket,$this->qcos_config['region'],$queryurl, $params, $authorization); $result =$data['AccessControlList']['Grant']; foreach($result as $v){ if($v['Permission'] == 'READ') $readperm= 2; } $setarr = ['cachekey' => $aclpermcache, 'cachevalue' => $readperm, 'dateline' => time()]; C::t('cache')->insert_cachedata_by_cachename($setarr,3600); return $readperm; } } /** * 移动附件 * @param $path * @param $attach * * @return array|bool|void */ public function MoveToSpace($path, $attach) { $filename = substr($path, strrpos($path, '/') + 1);; $fpath = substr($path, 0, strrpos($path, '/')) . '/'; if ($re = $this->makeDir($fpath)) { //创建目录 if ($re['error']) return $re; } $obz = io_remote::getBzByRemoteid($attach['remote']); $save_path = array(); if ($obz == 'dzz') { $opath = 'attach::' . $attach['aid']; } else { $opath = $obz . '/' . $attach['attachment']; } if ($re = $this->multiUpload($opath, $fpath, $filename, $attach, 'overwrite')) { if ($re['error']) return $re; else { return true; } } return false; } /** * 根据文件路径创建文件夹 * @param $path * @param string $pfid * @param bool $noperm */ public function createFolderByPath($path, $pfid = '', $noperm = false) { $data = array(); if (self::makeDir($path)) { $data = self::getMeta($path); } return $data; } public function makeDir($path) { $arr = $this->parsePath($path); $patharr = explode('/', trim($arr['object'], '/')); $folderarr = array(); $p = $arr['bz'] . $arr['bucket']; foreach ($patharr as $value) { $p .= '/' . $value; $re = $this->_makeDir($p); if (isset($re['error'])) { return $re; } } return true; } protected function _makeDir($path) { global $_G; $arr = self::parsePath($path); $qcos = self::init($path); if (is_array($qcos) && $qcos['error']) return $qcos; try { $ret = $qcos->putObject(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'] . '/', 'Body' => '')); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } return true; } //获取权限 public function getBucketALC($path) { $arr = self::parsePath($path); $qcos = self::init($path, 1); if (is_array($qcos) && $qcos['error']) return $qcos; $this->alc = $qcos->getObjectAcl(array($arr['bucket'], $arr['object'])); return $this->alc; } //获取存储桶列表 public function getBucketList($access_id, $access_key, $region) { $re = array(); $config = [ 'credentials' => array( 'secretId' => $access_id, 'secretKey' => $access_key ), 'region' => $region, 'schema' => 'http', ]; $qcos = new \Qcloud\Cos\Client($config); try { //请求成功 if ($list = $qcos->listBuckets()) { foreach ($list['Buckets'][0] as $value) { $re[] = $value['Name']; } } else { return array(); } } catch (\Exception $e) { //请求失败 //echo($e); return array('error' => $e->getMessage()); } return $re; } public function authorize($refer = '') { global $_G, $_GET, $clouds; if (empty($_G['uid'])) { dsetcookie('_refer', rawurlencode(BASESCRIPT . '?mod=connect&op=oauth&bz=qcos')); } if (submitcheck('addspace')) { $access_id = trim($_GET['access_id']); $access_key = trim($_GET['access_key']); $region = trim($_GET['region']); $bucket = trim($_GET['bucket']); $host = trim($_GET['host']); $extra = $_GET['extra']; $cloudname = $_GET['coludname'] ? trim($_GET['coludname']):$bucket; $urlarr = parse_url($host); if (!$access_id || !$access_key) { exit(json_encode(array('success'=>false,'msg'=>lang('input_QCOS_acc_sec') . 'Access Key ID and Access Key Secret'))); } if (!$bucket) exit(json_encode(array('success'=>false,'msg'=>'select_bucket_node_address'))); $qcos_config = [ 'credentials' => array( 'secretId' => $access_id, 'secretKey' => $access_key), 'region' => $region, 'schema' =>$urlarr['scheme'] ? $urlarr['scheme']:'http' ]; $checkdata = $this->checkqcos($qcos_config,$bucket); if(isset($checkdata['error'])){ exit(json_encode(array('success'=>false,'msg'=>$checkdata['error']))); } $cosClient = new Qcloud\Cos\Client($qcos_config); $type = 'QCOS'; $uid = defined('IN_ADMIN') ? 0 : $_G['uid']; //特殊参数 $specilext = []; if(isset($_GET['sign'])){ $specilext['sign'] = trim($_GET['sign']); $specilext['category'] = isset($_GET['category']) ? trim($_GET['category']):'A'; } $specialext = serialize($specilext); $setarr = array( 'cloudname'=>$cloudname, 'uid' => $uid, 'access_id' => $access_id, 'access_key' => dzzencode($access_key, $type,0), 'bz' => $type, 'bucket' => $bucket, 'dateline' => TIMESTAMP, 'hostname' => $qcos_config['schema'] . ':' . $region, 'host'=>$host, 'extra'=>serialize($extra), 'specialext'=>$specialext ); if ($id = DB::result_first("select id from " . DB::table(self::T) . " where uid='{$uid}' and access_id='{$access_id}' and bucket='{$bucket}'")) { DB::update(self::T, $setarr, "id ='{$id}'"); } else { $setarr['cloudname'] = C::t('connect_storage')->getcloudname($setarr['cloudname']); $id = DB::insert(self::T, $setarr, 1); } exit(json_encode(array('success'=>true))); } } //验证腾讯云可用性 public function checkqcos($config,$bucket){ //实例化类 $qcosclient = new Qcloud\Cos\Client($config); $foldername = 'pichomethumb/'; //创建目录 try{ $return = $qcosclient->putObject(array('Bucket'=>$bucket,'Key'=>$foldername,'Body'=>''));; } catch (Exception $e) { return array('error' => $e->getMessage()); } if(isset($return['error'])){ return array( 'error' =>$return['error']); } //创建临时上传目录 $datafoldername = 'tmpupload/'; //创建目录 try{ $return = $qcosclient->putObject(array('Bucket'=>$bucket,'Key'=>$datafoldername,'Body'=>''));; } catch (Exception $e) { return array('error' => $e->getMessage()); } if(isset($return['error'])){ return array( 'error' =>$return['error']); } //创建测试文件 $filename = $foldername.'/testapi.txt'; $filecontent = '123'; try { $ret = $qcosclient->Upload($bucket, $filename, $filecontent); } catch (Exception $e) { return array('error' => $e->getMessage()); } //获取文件地址 try { $return = $qcosclient->getObjectUrl($bucket,$filename,'+120 minutes');; }catch (Exception $e) { return array('error' => $e->getMessage()); } if(isset($return['error'])){ return array( 'error' =>$return['error']); }else{ //对比文件内容 if(file_get_contents($return) !== $filecontent){ return array( 'error' =>'read is error'); } } //删除文件 try { $response = $qcosclient->deleteObject(array('Bucket' =>$bucket, 'Key' =>$filename)); } catch (Exception $e) { return array( 'error' => $e->getMessage()); } return true; } public function getBzByPath($path) { $bzarr = explode(':', $path); return $bzarr[0] . ':' . $bzarr[1] . ':'; } //获取文件地址 public function getStream($path) { $arr = self::parsePath($path); $qcos = self::init($path, 1); if (is_array($qcos) && $qcos['error']) return $qcos; $readperm = self::getAclPerm(); $hostdata = explode(':',$arr['hostname']); $bucketurl = $hostdata[0].'://'.$arr['bucket'].'.cos.'.$hostdata[1].'.myqcloud.com'; if($readperm == 2 ){ return $d = ($this->host) ? $this->host .'/'. $arr['object']:$bucketurl.'/'.$arr['object']; }else{ return $qcos->getObjectUrl($arr['bucket'], $arr['object'], '+120 minutes'); } } public function uploadByStream($path,$filename,$file,$pfid,$relativePath='',$nohook=0){ global $_G; $arr = self::parsePath($path); $bzarr = explode(':',$arr['bz']); $data['remoteid']=DB::result_first("select remoteid from %t where did = %d",array('local_storage',$bzarr[1])); //获取上传的目标目录 $dirarr = explode('/', $relativePath); //如果有不存在的目录则创建之 $relativepath = !empty($dirarr) ? implode('/', $dirarr) : ''; $datas = array(); $datas['pfid'] = $pfid; if ($relativepath) { $datas = IO::createFolderByPath($relativepath, $pfid); $pfid = $datas['pfid']; } //获取文件md5 $md5 = md5_file($file); if($md5){ $attachment = C::t('attachment')->fetch_by_md5($md5); } //如果文件已经在附件表存在,调用秒传,返回结果 if($attachment){ $data['icoarr'][] = io_dzz::secondUpload($filename,$attachment,$pfid,1,1); if(isset($data['icoarr']['error'])){ return array('errormsg'=>$data['icoarr']['error']); }else{ return $data; } } else{ $data['md5'] = $md5; $data['size'] = filesize($file); $pathinfo = pathinfo($path); $ext = strtolower($pathinfo['extension']); $filepath = $arr['object']; $attachment = array( 'filesize' => $data['size'], 'attachment' => $filepath, 'filetype' => $ext, 'filename' => $filename, 'remote' => $data['remoteid'], 'copys' => 0, 'md5' => $data['md5'], 'unrun' => 0, 'dateline' => $_G['timestamp'], ); //获取文件路由对应位置 $routeremoteid = C::t('local_router')->getRemoteId($attachment); //如果路由位置和当前文件位置不同,则移动临时区文件到路由所指定位置 if ($routeremoteid && $routeremoteid != $data['remoteid']) { $localdata = C::t('local_storage')->fetch($routeremoteid); //如果路由位置为本地则直接赋值路径 if($localdata['bz'] == 'dzz') { $path = 'dzz::'.$filepath; } else { $did = $localdata['did']; $connectdata = C::t('connect_storage')->fetch($did); $path = $localdata['bz'] . ':' . $did . ':' . $connectdata['bucket'] . '/' . $filepath; } $attachment['remote'] = $routeremoteid; } $return = IO::moveThumbFile($path,$file); if(!isset($return['error'])){ $attachment['attachment'] = $arr['object']; //第三个参数代表由服务器端上传,控制挂载点调用 $attachment['aid'] = C::t('attachment')->insert($attachment, 1,$nohook); //文件上传至目标位置后的数据库数据处理 $datas['icoarr'][] = self::uploadToattachment($attachment, $pfid,$nohook); return $datas; }else{ return $return; } } } public function deleteThumb($path) { global $_G; $imgcachePath = './imgcache/'; $cachepath = str_replace('//', '/', str_replace(':', '/', $path)); foreach ($_G['setting']['thumbsize'] as $value) { $target = $imgcachePath . ($cachepath) . '.' . $value['width'] . '_' . $value['height'] . '_1.jpeg'; $target1 = $imgcachePath . ($cachepath) . '.' . $value['width'] . '_' . $value['height'] . '_2.jpeg'; @unlink($_G['setting']['attachdir'] . $target); @unlink($_G['setting']['attachdir'] . $target1); } } public function parseparams($signedUrl, $width, $height, $thumbtype,$format='webp') { //横图按高度给比例值 竖图按宽度比例给值 $imginfo = @getimagesize($signedUrl); $imgwidth = $imginfo[0]; $imgheight = $imginfo[1]; if ($imgwidth > 9999 || $imgheight > 9999) { return false; } //如果缩略图宽高大于等于原图宽高则不生成缩略图 if($width>= $imgwidth || $height>= $imgheight){ return ''; } $oscale = $imgwidth / $imgheight; $nscale = $width /$height; if ($thumbtype == 2) { /* if ($oscale > $nscale) { $width = $width/$oscale; $height= $height; } else { $width = $width; $height = $height*$oscale; }*/ if ($oscale > $nscale) { //按高度度等比剪裁 return 'imageMogr2/format/'.$format.'/thumbnail/x' . $height . '/|imageMogr2/gravity/center/crop/' . $width . 'x' . $height . '/interlace/0'; } else { //按宽度等比剪裁 return 'imageMogr2/format/'.$format.'thumbnail/' . $width . 'x' . '/|imageMogr2/gravity/north/crop/' . $width . 'x' . $height . '/interlace/0'; } } else { if ($oscale > $nscale) { $width = $width; $height= $height/$oscale; } else { $height = $height; $width = $width*$oscale; } if ($oscale > $nscale) { //按宽度等比缩放 return 'imageMogr2/format/'.$format.'/thumbnail/' . $width . 'x' . '/interlace/0'; } else { //按高度度等比缩放 return 'imageMogr2/format/'.$format.'/thumbnail/x' . $height . '/interlace/0'; } } } //获取缩略图地址 public function getwaterimg($path){ $arr = self::parsePath($path); $qcos = self::init($path, 1); if (is_array($qcos) && $qcos['error']) return $qcos; $readperm = self::getAclPerm(); $hostdata = explode(':',$arr['hostname']); $bucketurl = $hostdata[0].'://'.$arr['bucket'].'.cos.'.$hostdata[1].'.myqcloud.com'; if($readperm == 2 ){ return $d = ($this->host) ? $this->host .'/'. $arr['object']:$bucketurl.'/'.$arr['object']; }else{ $auth = $this->getAuthorization($this->qcos_config['credentials']['secretId'], $this->qcos_config['credentials']['secretKey'],$arr['object']); $d = ($this->host) ? $this->host .'/'. $arr['object']:$bucketurl.'/'.$arr['object']; return $d.'?sign='.urlencode($auth); } } public function parsewatermarkparams($signedUrl,$extraparams,$width,$height){ global $_G; if(!$_G['setting']['IsWatermarkstatus']) return false; //横图按高度给比例值 竖图按宽度比例给值 $imginfo = @getimagesize($signedUrl); $imgwidth = $imginfo[0]; $imgheight = $imginfo[1]; if ($imgwidth > 9999 || $imgheight > 9999) { return false; } //如果缩略图宽高大于等于原图宽高则不生成缩略图 /* if($width>= $imgwidth && $height>= $imgheight){ return ''; }*/ //1920 1080 3600 720 640 360 1920/1080 $oscale = $imgwidth / $imgheight; $nscale = $width /$height; if ($oscale > $nscale) { $width = $width; $height= $height/$oscale; } else { $height = $height; $width = $width*$oscale; } if (!($_G['setting']['watermarkstatus'] || $extraparams['position_text'] || $extraparams['position'])) { return ''; } if(($_G['setting']['watermarkminwidth'] && $width <= $_G['setting']['watermarkminwidth']) || ($_G['setting']['watermarkminheight'] && $height <= $_G['setting']['watermarkminheight'])){ return ''; } $watermarktype = ($extraparams['watermarktype']) ? $extraparams['watermarktype']:$_G['setting']['watermarktype']; $watermarktext = ($extraparams['watermarktext']) ? $extraparams['watermarktext']:$_G['setting']['watermarktext']; $gravity = 'center'; switch ($_G['setting']['watermarkstatus']) { /* 右下角水印 */ case 9: $gravity = 'southeast'; break; /* 左下角水印 */ case 7: $gravity = 'southwest'; break; /* 左上角水印 */ case 1: $gravity = 'northwest'; break; /* 右上角水印 */ case 3: $gravity = 'northeast'; break; /* 居中水印 */ case 5: $gravity = 'center'; break; /* 下居中水印 */ case 8: $gravity = 'south'; break; /* 右居中水印 */ case 6: $gravity = 'east'; break; /* 上居中水印 */ case 2: $gravity = 'north'; break; /* 左居中水印 */ case 4: $gravity = 'west'; break; default: $gravity = 'center'; } $dx = $watermarktext['skewx']? $watermarktext['skewx']:0; $dy = $watermarktext['skewy'] ? $watermarktext['skewy']:0 ; if($watermarktype != 'text'){ // echo \IO::getStream($extraparams['waterimg']);die; $imgurl = IO::getwaterimg($extraparams['waterimg']); $imgurl = str_replace('https','http',$imgurl); $imgurl = base64_encode($imgurl); //$imgurl = base64_encode('http://pichome2-1300250401.cos.ap-beijing.myqcloud.com/static/waterimg/water.png'); $imgurl = str_replace(array('+','/'),array('-','_'),$imgurl); return 'watermark/1/image/'.$imgurl.'/gravity/'.$gravity.'/dx/'.$dx.'/dy/'.$dy; }else{ $text =$watermarktext['textfull']; $text = base64_encode($text); $colorarr = explode(',',$watermarktext['color']); if(!empty($colorarr)){ $color = 'rgb('.$colorarr[0].','.$colorarr[1].','.$colorarr[2].')'; $color = $this->RGBToHex($color); $dissolve = isset($colorarr[3]) ? $colorarr[3]:90; }else{ $color = $watermarktext['color']; } $color = base64_encode($color); $fontsize = $watermarktext['size']; return 'watermark/2/text/'.$text.'/fill/'.$color.'/fontsize/'.$fontsize.'/gravity/'.$gravity.'/dx/'.$dx.'/dy/'.$dy; } //http://examples-1251000004.cos.ap-shanghai.myqcloud.com/sample.jpeg?watermark/2/text/6IW-6K6v5LqRwrfkuIfosaHkvJjlm74/fill/IzNEM0QzRA/fontsize/20/dissolve/50/gravity/northeast/dx/20/dy/20/batch/1/degree/45 //return 'watermark/2/text/'.$text.'/fill/IzNEM0QzRA/fontsize/20/gravity/center'; } function RGBToHex($rgb){ $regexp = "/^rgb\(([0-9]{0,3})\,\s*([0-9]{0,3})\,\s*([0-9]{0,3})\)/"; $re = preg_match($regexp, $rgb, $match); $re = array_shift($match); $hexColor = "#"; $hex = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'); for ($i = 0; $i < 3; $i++) { $r = null; $c = $match[$i]; $hexAr = array(); while ($c > 16) { $r = $c % 16; $c = ($c / 16) >> 0; array_push($hexAr, $hex[$r]); } array_push($hexAr, $hex[$c]); $ret = array_reverse($hexAr); $item = implode('', $ret); $item = str_pad($item, 2, '0', STR_PAD_LEFT); $hexColor .= $item; } return $hexColor; } public function createThumbByOriginal($path, $data,$width = 0, $height = 0, $thumbtype = 1, $original = 0, $extraparams = array(),$filesize=0) { global $_G; $filedirpathinfo = pathinfo($path); $filedirextensionarr = explode('?', $filedirpathinfo['extension']); $filedirextension = strtolower($filedirextensionarr[0]); $patharr = explode(':',$path); //print_r($patharr);die; // $did = $patharr[1]; //$connectdata = C::t('connect_storage')->fetch($did); $arr = self::parsePath($path); $cachename = 'PICHOMETHUMBSTATUS'; $thumbstatus = C::t('cache')->fetch_cachedata_by_cachename($cachename); if (!$thumbstatus) { $thunbdata = []; foreach(DB::fetch_all("select id,bz,mediastatus from %t where 1",array('connect_storage')) as $v){ if($v['bz'] == 'dzz'){ $key = $v['bz'].'::'; }else{ $key = $v['bz'].':'.$v['id'].':'; } $thunbdata[$key] = intval($v['mediastatus']); } $setarr = ['cachekey' => $cachename, 'cachevalue' => serialize($thunbdata), 'dateline' => time()]; C::t('cache')->insert_cachedata_by_cachename($setarr); } else { $thunbdata = $thumbstatus; } $cbz = $patharr[0].':'.$patharr[1].':'; if(isset($thunbdata[$cbz])){ $imgstate = $thunbdata[$cbz]; } //如果文件大小超过32M,尝试使用本地缩略图转换处理 if(!$imgstate || $filesize > 1024*1024*32){ return io_dzz::createThumbByOriginal($path, $data,$width, $height ,$thumbtype, $original , $extraparams,$filesize); } else{ $qcosimageexts = getglobal('config/qcosimage') ? explode(',',getglobal('config/qcosimage')):array('jpeg','jpg', 'png', 'gif', 'webp','bmp'); if(!in_array($filedirextension,$qcosimageexts)){ return io_dzz::createThumbByOriginal($path, $data,$width, $height ,$thumbtype, $original , $extraparams,$filesize); } if($filedirextension == 'gif'){ $thumbext = 'gif'; }else{ $thumbext = 'webp'; } $signedUrl = $this->getStream($path); $params = ''; if(!$original){ $params = $this->parseparams($signedUrl, $width, $height, $thumbtype,$thumbext); } $waterparams = ''; if($extraparams['watermarkstatus'] && !$extraparams['watermarktext']){ //获取水印图片地址 $extraparams['waterimg'] = $arr['bz'].'static/waterimg/water.png'; } //水印参数 $waterparams = $this->parsewatermarkparams($signedUrl,$extraparams,$width, $height); if($params || $waterparams){ $hassign = strpos($signedUrl,'?') === false ? false:true; $url = $signedUrl.($hassign ? '&':'?').$params.($waterparams ? ($params ? '|'.$waterparams:$waterparams):''); }else{ $url = $signedUrl; } } if(!$url) return false; $extraflag = ''; if ($_G['setting']['watermarkstatus'] || $extraparams['position_text'] || $extraparams['position']) { $extraflag .= '_w'; } if ($extraparams['watermarktype']) { $extraflag .= '_' . $extraparams['watermarktype']; } if ($extraparams['watermarktype']['watermarktext']) { $extraflag .= '_' . $extraparams['watermarktext']; } //如果是生成临时图 if($extraparams['istmp']){ return $url; } $thumbpath = self::getthumbpath('pichomethumb'); if($data['aid'])$thumbname = md5($data['aid'].$data['thumbsign'].$extraflag).'_'.$data['thumbsign'].'.'.$thumbext; else $thumbname = md5($data['path'].$data['thumbsign'].$extraflag).'_'.$data['thumbsign'].'.'.$thumbext; $thumbpath = $thumbpath.$thumbname; $defaultspace = $_G['setting']['defaultspacesetting']; if($defaultspace['bz'] == 'dzz::'){ $cloudpath = $defaultspace['bz'].'::/' .$thumbpath; }else{ $cloudpath = $defaultspace['bz'].':'.$defaultspace['did'] . ':/' .$thumbpath; } $return = IO::moveThumbFile($cloudpath,$url); if(isset($return['error'])){ return false; }else{ return $thumbpath; } } //判断文件或目录是否存在 function checkfileexists($path,$isdir = false){ $arr = self::parsePath($path); $qcos = self::init($path, 1); if (is_array($qcos) && $qcos['error']) return array('error'=>$qcos); try{ $object = ($isdir && substr($arr['object'], -1) != '/') ? $arr['object'].'/':$arr['object']; $result = $qcos->doesObjectExist($arr['bucket'],$object); if(!$result){ if($isdir){ try{ $result = $qcos->listObjects( ['Bucket' => $arr['bucket'], 'Delimiter'=>'/', 'Marker' => '', 'Prefix' => $object, 'MaxKeys' => 1] ); //runlog('aaareturn',print_r($result,true)); }catch (Exception $e){ return false; } //if($result['CommonPrefixes']){ return true; // } } return false; } }catch (Exception $e){ return false; } return true; } public function generate_url($path){ $arr = self::parsePath($path); if($this->host){ if(isset($arr['extra']['sign'])){ $uri = '/'.$arr['object']; $sign = $arr['extra']['sign']; $category = $arr['extra']['category']; $time = time(); $rand = random(6); if($category == 'A'){ $md5hash = md5($uri.'-'.$time.'-'.$rand.'-0-'.$sign); $url =$this->host.$uri.'?sign='.$time.'-'.$rand.'-0-'.$md5hash; }elseif($category == 'B'){ $md5hash = md5($sign.$time.$uri); $url =$this->host.'/'.$time.'/'.$md5hash.$uri; }elseif($category == 'C'){ $time = dechex($time); $md5hash = md5($sign.$path.$time); $url =$this->host.'/'.$md5hash.'/'.$time.$uri; }elseif($category == 'D'){ $md5hash = md5($sign.$uri.$time); $url =$this->host.$uri.'?sign='.$md5hash.'&t='.$time; } }else{ $url = $this->host .'/'. $arr['object']; } }else{ $qcos = self::init($path, 1); $url = $qcos->getObjectUrl($arr['bucket'], $arr['object'], '+120 minutes'); } return $url; } //获取文件流; //$path: 路径 function getFileUri($path,$fileexists = false) { $arr = self::parsePath($path); $qcos = self::init($path, 1); if (is_array($qcos) && $qcos['error']) return array('error'=>$qcos); /* if($fileexists){ try{ $result = $qcos->doesObjectExist($arr['bucket'],$arr['object']); if(!$result){ return array('error'=>'文件不存在');//后面修改为语言包 } }catch (Exception $e){ return array('error'=>$e->getMessage()); } }*/ $readperm = self::getAclPerm(); $hostdata = explode(':',$arr['hostname']); $bucketurl = $hostdata[0].'://'.$arr['bucket'].'.cos.'.$hostdata[1].'.myqcloud.com'; if($readperm == 2 ){ $d = ($this->host) ? 'https://'.$this->host .'/'. $arr['object']:$bucketurl.'/'.$arr['object']; }else{ $d = $qcos->getObjectUrl($arr['bucket'], $arr['object'], '+120 minutes'); if($this->host) { $secret_id = $this->qcos_config['credentials']['secretId']; $secret_key = $this->qcos_config['credentials']['secretKey']; $StartTimestamp = time(); $EndTimestamp = $StartTimestamp + 7200; //请求头 $headers = []; $fileUri = '/'. $arr['object']; $authorization = $this->get_authorization($secret_key,$secret_id,$StartTimestamp, $EndTimestamp, $fileUri, $headers); $d = 'https://'.$this->host .'/'. $arr['object'].'?'. $authorization; } } $d = str_replace('#','%23',$d); return $d; } public function parsePath($path) { $path = str_replace(BS,'/',$path); $arr = explode(':', $path); $bz = $arr[0] . ':' . $arr[1] . ':'; //$arr1 = explode('/', $arr[2]); $connect = DB::fetch_first("select * from %t where id = %d",array('connect_storage',$arr[1])); $bucket = $connect['bucket']; $hostname = $connect['hostname']; // unset($arr1[0]); $object = $arr[2]; return array('bucket' => $bucket, 'object' => $object, 'bz' => $bz,'hostname'=>$hostname,'extra'=>unserialize($connect['specialext'])); } //重写文件内容 //@param number $path 文件的路径 //@param string $data 文件的新内容 public function setFileContent($path, $data) { $arr = self::parsePath($path); $qcos = self::init($path); if (is_array($qcos) && $qcos['error']) return $qcos; try { $ret = $qcos->Upload($arr['bucket'], $arr['object'], $data); $meta = array( 'Key' => $arr['object'], 'Size' => strlen($data), 'LastModified' => dgmdate(TIMESTAMP, 'Y-m-d H:i:s'), ); $icoarr = self::_formatMeta($meta, $arr); return $icoarr; } catch (ErrorException $e) { return array('error' => $e->getMessage()); } } /** * 上传文件 * * @param string $fileContent 文件内容字符串 * @param string $path 上传文件的目标保存路径 * @param string $fileName 文件名 * @param string $ondup overwrite:目前只支持覆盖。 * * @return string */ function upload_by_content($fileContent, $path, $filename, $ondup = 'overwrite') { global $_G; $path .= $filename; $arr = self::parsePath($path); $qcos = self::init($path); if (is_array($qcos) && $qcos['error']) return $qcos; try { $ret = $qcos->Upload($arr['bucket'], $arr['object'] . '/' . $filename, $fileContent); $meta = array( 'Key' => $arr['object'] . '/' . $filename, 'Size' => strlen($fileContent), 'LastModified' => dgmdate(TIMESTAMP, 'Y-m-d H:i:s'), ); $icoarr = self::_formatMeta($meta, $arr); return $icoarr; } catch (Exception $e) { return array('error' => $e->getMessage()); } } /** * 获取当前用户空间配额信息 * * @return string */ public function getQuota($bz) { return 0; } function getFolderlist($path, $nextmarker = '',$by = 'time',$order = 'DESC', $limit = 1000, $force = 0){ $arr = self::parsePath($path); $folderdatas = $folders = []; $folderdatas['IsTruncated'] = false; $folderdatas['NextMarker'] = ''; $qcos = self::init($path); if (is_array($qcos) && $qcos['error']) return $qcos; try { $querydata = array( 'Bucket' => $arr['bucket'], 'Delimiter' => '/', 'Marker' => ($nextmarker) ? $nextmarker:$arr['object'], 'MaxKeys' => $limit, ); if($arr['object'] == '/') $arr['object'] = ''; if($arr['object']) $querydata['Prefix'] = $arr['object'].'/'; //else $querydata['Prefix'] = '/'; $data = $qcos->listObjects($querydata); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } foreach ($data['CommonPrefixes'] as $v) { if($v['Prefix'] != 'dzz/' && $v['Prefix'] != 'static/' && $v['Prefix'] != 'pichomethumb/' && $v['Prefix'] != 'tmpupload/'){ $folders[] = $v['Prefix']; } } if($data['IsTruncated']){ $folderdatas['IsTruncated'] = true; $folderdatas['NextMarker'] = $data['NextMarker']; } $folderdatas['folder'] = $folders; return $folderdatas; } /** * 获取指定文件夹下的文件列表 * * @param string $path 文件路径 * @param string $by 排序字段,缺省根据文件类型排序,time(修改时间),name(文件名),size(大小,注意目录无大小) * @param string $order asc或desc,缺省采用降序排序 * @param string $limit 返回条目控制,参数格式为:n1-n2。返回结果集的[n1, n2)之间的条目,缺省返回所有条目。n1从0开始。 * @param string $force 读取缓存,大于0:忽略缓存,直接调用api数据,常用于强制刷新时。 * * @return icosdatas */ function listFiles($path, $nextmarker = '',$by = 'time',$order = 'DESC', $limit = 1000, $force = 0) { $arr = self::parsePath($path); $datas = $folders = $files = []; $datas['IsTruncated'] = false; $datas['NextMarker'] = ''; $qcos = self::init($path); if (is_array($qcos) && $qcos['error']) return $qcos; try { $querydata = array( 'Bucket' => $arr['bucket'], 'Delimiter' => '/', 'Marker' => ($nextmarker) ? $nextmarker:$arr['object'], 'MaxKeys' => $limit, ); if($arr['object']) $querydata['Prefix'] = $arr['object'].'/'; //if($nextmarker) print_r($querydata);die; $data = $qcos->listObjects($querydata); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } foreach($data['Contents'] as $v){ if($v['Size'] > 0){ $files[] = $v['Key']; } } foreach ($data['CommonPrefixes'] as $v) { if($v['Prefix'] != 'pichomethumb/'){ $folders[] = $v['Prefix']; } } if($data['IsTruncated']){ $datas['IsTruncated'] = true; $datas['NextMarker'] = $data['NextMarker']; } $datas['folder'] = $folders; $datas['file'] = $files; return $datas; } //获取图片信息 function getImagedatabyPath($path){ $ch = curl_init(); $url = $this->getStream($path); if(strpos($url,'?') !== false){ $url .= '&imageInfo'; }else{ $url .= '?imageInfo'; } curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); if (!empty($arr_header)) { curl_setopt($ch, CURLOPT_HTTPHEADER, $arr_header); } curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_REFERER, ''); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); $response = curl_exec($ch); $data = json_decode($response,true); curl_close($ch); return $data; } /* *获取文件的meta数据 *返回标准的icosdata *$force>0 强制刷新,不读取缓存数据; */ function getMeta($path, $getimagedata = 0) { $arr = self::parsePath($path); $icosdata = array(); $qcos = self::init($path, 1); if (is_array($qcos) && $qcos['error']) return $qcos; if (empty($arr['object']) || empty($arr['bucket'])) { $meta = array( 'Key' => '', 'Size' => 0, 'LastModified' => '', 'isdir' => true ); } else { try { $meta = $qcos->headObject(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'])); if($getimagedata && strpos($meta['ContentType'],'image') === 0){ $imagedata = $this->getImagedatabyPath($path); }else{ $imagedata = array(); } $ext = substr(strrchr($meta['Key'], '.'), 1); $ext = strtolower($ext); $metatmp = array( 'dateline'=>strtotime($meta['LastModified']), 'size'=>$meta['ContentLength'], 'filename'=>basename($meta['Key']), 'ext'=>$ext ); $meta = array_merge($metatmp,$imagedata); } catch (Exception $e) { return array('error' => $e->getMessage()); } } return $meta; } //将api获取的meta数据转化为icodata function _formatMeta($meta, $arr) { global $_G, $documentexts, $imageexts; $icosdata = array(); ///print_r($meta);print_r($arr);exit($this->bucket); if (substr($meta['Key'], -1) == '/') $meta['isdir'] = true; if ($meta['isdir']) { if (!$meta['Key']) { if ($this->bucket) { $name = $this->bucket; $pfid = 0; $pf = ''; $flag = self::BZ; } elseif ($arr['bucket']) { $name = $arr['bucket']; $pfid = md5($arr['bz']); $pf = ''; $flag = self::BZ; } else { $name = $this->_rootname; $pfid = 0; $pf = ''; $flag = self::BZ; } if ($arr['bucket']) $arr['bucket'] .= '/'; } else { if ($arr['bucket']) $arr['bucket'] .= '/'; $namearr = explode('/', $meta['Key']); $name = $namearr[count($namearr) - 2]; $pf = ''; for ($i = 0; $i < (count($namearr) - 2); $i++) { $pf .= $namearr[$i] . '/'; } $pf = $arr['bucket'] . $pf; $pfid = md5($arr['bz'] . $pf); $flag = ''; } //print_r($arr); //print_r($namearr); $icoarr = array( 'icoid' => md5(($arr['bz'] . $arr['bucket'] . $meta['Key'])), 'path' => $arr['bz'] . $arr['bucket'] . $meta['Key'], 'dpath' => dzzencode($arr['bz'] . $arr['bucket'] . $meta['Key']), 'bz' => ($arr['bz']), 'gid' => 0, 'name' => $name, 'username' => $_G['username'], 'uid' => $_G['uid'], 'oid' => md5($arr['bz'] . $arr['bucket'] . $meta['Key']), 'img' => 'dzz/images/default/system/folder.png', 'type' => 'folder', 'ext' => '', 'pfid' => $pfid, 'ppath' => $arr['bz'] . $pf, 'size' => 0, 'dateline' => strtotime($meta['LastModified']), 'flag' => $flag, 'nextMarker' => $meta['nextMarker'], 'IsTruncated' => $meta['IsTruncated'], ); $icoarr['fsize'] = formatsize($icoarr['size']); $icoarr['ftype'] = getFileTypeName($icoarr['type'], $icoarr['ext']); $icoarr['fdateline'] = dgmdate($icoarr['dateline']); $icosdata = $icoarr; /*print_r($icosdata); exit($meta['Key']);*/ } else { if ($arr['bucket']) $arr['bucket'] .= '/'; $namearr = explode('/', $meta['Key']); $name = $namearr[count($namearr) - 1]; $pf = ''; for ($i = 0; $i < count($namearr) - 1; $i++) { $pf .= $namearr[$i] . '/'; } $ext = strtoupper(substr(strrchr($meta['Key'], '.'), 1)); if (in_array($ext, $imageexts)) $type = 'image'; elseif (in_array($ext, $documentexts)) $type = 'document'; else $type = 'attach'; if ($type == 'image') { $img = $_G['siteurl'] . DZZSCRIPT . '?mod=io&op=thumbnail&size=small&path=' . dzzencode($arr['bz'] . $arr['bucket'] . $meta['Key']); $url = $_G['siteurl'] . DZZSCRIPT . '?mod=io&op=thumbnail&size=large&path=' . dzzencode($arr['bz'] . $arr['bucket'] . $meta['Key']); } else { $img = geticonfromext($ext, $type); $url = $_G['siteurl'] . DZZSCRIPT . '?mod=io&op=getStream&path=' . dzzencode($arr['bz'] . $arr['bucket'] . $meta['Key']);; } $icoarr = array( 'icoid' => md5(($arr['bz'] . $arr['bucket'] . $meta['Key'])), 'path' => ($arr['bz'] . $arr['bucket'] . $meta['Key']), 'dpath' => dzzencode($arr['bz'] . $arr['bucket'] . $meta['Key']), 'bz' => ($arr['bz']), 'gid' => 0, 'name' => $name, 'username' => $_G['username'], 'uid' => $_G['uid'], 'oid' => md5(($arr['bz'] . $arr['bucket'] . $meta['Key'])), 'img' => $img, 'url' => $url, 'type' => $type, 'ext' => strtolower($ext), 'pfid' => md5($arr['bz'] . $arr['bucket'] . $pf), 'ppath' => $arr['bz'] . $arr['bucket'] . $pf, 'size' => $meta['Size'], 'dateline' => strtotime($meta['LastModified']), 'flag' => '' ); $icoarr['fsize'] = formatsize($icoarr['size']); $icoarr['ftype'] = getFileTypeName($icoarr['type'], $icoarr['ext']); $icoarr['fdateline'] = dgmdate($icoarr['dateline']); $icosdata = $icoarr; } return $icosdata; } //根据路径获取目录树的数据; public function getFolderDatasByPath($path) { $bzarr = self::parsePath($path); $oss = self::init($path, 1); $spath = $bzarr['object']; if (!$this->bucket && $bzarr['bucket']) { $spath = $bzarr['bucket'] . '/' . $spath; $bzarr['bucket'] = ''; } else { $bzarr['bucket'] .= '/'; } $spath = trim($spath, '/'); $patharr = explode('/', $spath); $folderarr = array(); $path1 = $bzarr['bz'] . $bzarr['bucket']; if ($arr = self::getMeta($path1)) { if (!isset($arr['error'])) { $folder = self::getFolderByIcosdata($arr); $folderarr[$folder['fid']] = $folder; } } for ($i = 0; $i < count($patharr); $i++) { $path1 = $bzarr['bz'] . $bzarr['bucket']; for ($j = 0; $j <= $i; $j++) { $path1 .= $patharr[$j] . '/'; } if ($arr = self::getMeta($path1)) { if (isset($arr['error'])) continue; $folder = self::getFolderByIcosdata($arr); $folderarr[$folder['fid']] = $folder; } } return $folderarr; } //通过icosdata获取folderdata数据 function getFolderByIcosdata($icosdata) { global $_GET; $folder = array(); //通过path判断是否为bucket $path = $icosdata['path']; $arr = self::parsePath($path); if (!$arr['bucket']) { //根目录 $fsperm = 0; } else { $fsperm = 0; } if ($icosdata['type'] == 'folder') { $folder = array( 'fid' => $icosdata['oid'], 'path' => $icosdata['path'], 'fname' => $icosdata['name'], 'uid' => $icosdata['uid'], 'pfid' => $icosdata['pfid'], 'ppath' => $icosdata['ppath'], 'iconview' => $_GET['iconview'] ? intval($_GET['iconview']) : 0, 'disp' => $_GET['disp'] ? intval($_GET['disp']) : 0, 'perm' => $this->perm, 'hash' => $icosdata['hash'], 'bz' => $icosdata['bz'], 'gid' => $icosdata['gid'], 'fsperm' => $fsperm, 'icon' => '', 'nextMarker' => $icosdata['nextMarker'], 'IsTruncated' => $icosdata['IsTruncated'], ); //print_r($folder); } return $folder; } //获得文件内容; function getFileContent($path) { $arr = self::parsePath($path); $url = self::getStream($path); return file_get_contents($url); } //打包下载文件 public function zipdownload($paths, $filename) { global $_G; $paths = (array)$paths; set_time_limit(0); if (empty($filename)) { $meta = self::getMeta($paths[0]); $filename = $meta['name'] . (count($paths) > 1 ? lang('wait') : ''); } $filename = (strtolower(CHARSET) == 'utf-8' && (strexists($_SERVER['HTTP_USER_AGENT'], 'MSIE') || strexists($_SERVER['HTTP_USER_AGENT'], 'Edge') || strexists($_SERVER['HTTP_USER_AGENT'], 'rv:11')) ? urlencode($filename) : $filename); include_once libfile('class/ZipStream'); $zip = new ZipStream($filename . ".zip"); $data = self::getFolderInfo($paths, '', $zip); /*if($data['error']){ topshowmessage($data['error']); exit(); }*/ /*foreach($data as $value){ $zip->addLargeFile(fopen($value['url'],'rb'), $value['position'], $value['dateline']); }*/ $zip->finalize(); } public function getFolderInfo($paths, $position = '', $zip) { static $data = array(); try { foreach ($paths as $path) { $arr = IO::parsePath($path); $oss = self::init($path, 1); if (is_array($oss) && $oss['error']) return $oss; $meta = self::getMeta($path); switch ($meta['type']) { case 'folder': $lposition = $position . $meta['name'] . '/'; $contents = self::listFilesAll($oss, $path); $arr = array(); foreach ($contents as $key => $value) { if ($value['path'] != $path) { $arr[] = $value['path']; } } if ($arr) self::getFolderInfo($arr, $lposition, $zip); break; default: $meta['url'] = self::getStream($meta['path']); $meta['position'] = $position . $meta['name']; //$data[$meta['icoid']]=$meta; $zip->addLargeFile(@fopen($meta['url'], 'rb'), $meta['position'], $meta['dateline']); } } } catch (Exception $e) { //var_dump($e); $data['error'] = $e->getMessage(); return $data; } return $data; } //下载文件 public function download($paths, $filename) { global $_G; $paths = (array)$paths; if (count($paths) > 1) { self::zipdownload($paths, $filename); exit(); } else { $path = $paths[0]; } $path = rawurldecode($path); //header("location: $url"); try { $url = self::getStream($path); // Download the file $file = self::getMeta($path); if ($file['type'] == 'folder') { self::zipdownload($path); exit(); } if (!$fp = @fopen($url, 'rb')) { topshowmessage(lang('file_not_exist1')); } $chunk = 10 * 1024 * 1024; //$file['data'] = self::getFileContent($path); //if($file['data']['error']) topshowmessage($file['data']['error']); $file['name'] = '"' . (strtolower(CHARSET) == 'utf-8' && (strexists($_SERVER['HTTP_USER_AGENT'], 'MSIE') || strexists($_SERVER['HTTP_USER_AGENT'], 'Edge') || strexists($_SERVER['HTTP_USER_AGENT'], 'rv:11')) ? urlencode($file['name']) : $file['name']) . '"'; $d = new FileDownload(); $d->download($url, $file['name'], $file['size'], $file['dateline'], true); exit(); dheader('Date: ' . gmdate('D, d M Y H:i:s', $file['dateline']) . ' GMT'); dheader('Last-Modified: ' . gmdate('D, d M Y H:i:s', $file['dateline']) . ' GMT'); dheader('Content-Encoding: none'); dheader('Content-Disposition: attachment; filename=' . $file['name']); dheader('Content-Type: application/octet-stream'); dheader('Content-Length: ' . $file['size']); @ob_end_clean(); if (getglobal('gzipcompress')) @ob_start('ob_gzhandler'); while (!feof($fp)) { echo fread($fp, $chunk); @ob_flush(); // flush output @flush(); } fclose($fp); exit(); } catch (Exception $e) { // The file wasn't found at the specified path/revision //echo 'The file was not found at the specified path/revision'; topshowmessage($e->getMessage()); } } //获取目录的所有下级和它自己的object public function getFolderObjects(&$qcos, $path, $limit = '1', $marker = '') { static $objects = array(); $arr = self::parsePath($path); try { $querydata = array( 'Bucket' => $arr['bucket'], 'Prefix'=>$arr['object'], 'Marker' => ($marker) ? $marker:$arr['object'], 'MaxKeys' => $limit ); print_r($querydata); $data = $qcos->listObjects($querydata); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } foreach ($data['Contents'] as $v) { $objects[] = $v['Key']; } if ($data['IsTruncated'] == 'true') { self::getFolderObjects($path, 1, $data['nextMarker']); } return $objects; } //删除原内容 //$path: 删除的路径 //$bz: 删除的api; //$data:可以删除的id数组(当剪切的时候,为了保证数据不丢失,目标位置添加成功后将此id添加到data数组, //删除时如果$data有数据,将会只删除id在$data中的数据; //如果删除的是目录或下级有目录,需要判断此目录内是否所有元素都在删除的id中,如果有未删除的元素,则此目录保留不会删除; // public function Delete($path, $isdir=false) { $arr = self::parsePath($path); try { $qcos = self::init($path); if (is_array($qcos) && $qcos['error']) return $qcos; //判断删除的对象是否为文件夹 if ($isdir || substr($arr['object'], -1) == '/') { //是文件夹 $cos_prefix = $arr['object']; $nextMarker = ''; $isTruncated = true; while ( $isTruncated ) { try { $result = $qcos->listObjects( [ 'Delimiter'=>'/', 'Bucket' => $arr['bucket'], 'Marker' => $nextMarker, 'Prefix' => $cos_prefix, 'MaxKeys' => 1000] ); $isTruncated = $result['IsTruncated']; $nextMarker = $result['NextMarker']; foreach ($result['Contents'] as $content ) { $cos_file_path = $content['Key']; try { $qcos->deleteObject(array( 'Bucket' => $arr['bucket'], 'Key' => $cos_file_path, )); } catch ( \Exception $e ) { return array('error' => $e->getMessage()); } } } catch ( \Exception $e ) { return array('error' => $e->getMessage()); } } } else { $response = $qcos->deleteObject(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'])); } if ($response === false) { return array('error' => 'error'); } return true; } catch (Exception $e) { return array( 'error' => $e->getMessage()); } } //添加目录 //$fname:目录路径; //$container:目标容器 //$bz:api; public function CreateFolder($path, $fname) { global $_G; $arr = self::parsePath($path); //exit('createrfolder==='.$fname.'===='.$path1.'===='.$bz); //exit($path.$fname.'vvvvvvvvvvv'); $return = array(); try { $qcos = self::init($path); if (is_array($qcos) && $qcos['error']) return $qcos; $ret = $qcos->putObjectByContent($arr['object'] . '/' . $fname . '/', ''); if ($ret === false) { return array('error' => self::get_error_info($qcos)); } $meta = array( 'isdir' => true, 'Key' => $arr['object'] . $fname . '/', 'Size' => 0, 'LastModified' => $ret->header['date'], ); $icoarr = self::_formatMeta($meta, $arr); $folderarr = self::getFolderByIcosdata($icoarr); $return = array('folderarr' => $folderarr, 'icoarr' => $icoarr); } catch (Exception $e) { //var_dump($e); $return = array('error' => $e->getMessage()); } return $return; } //获取不重复的目录名称 public function getFolderName($name, $path) { static $i = 0; if (!$this->icosdatas) $this->icosdatas = self::listFiles($path); $names = array(); foreach ($this->icosdatas as $value) { $names[] = $value['name']; } if (in_array($name, $names)) { $name = str_replace('(' . $i . ')', '', $name) . '(' . ($i + 1) . ')'; $i += 1; return self::getFolderName($name, $path); } else { return $name; } } private function getCache($path) { $cachekey = 'qcos_uploadID_' . md5($path); $cache = C::t('cache')->fetch($cachekey); return unserialize($cache['cachevalue']); } private function saveCache($path, $data) { global $_G; $cachekey = 'qcos_uploadID_' . md5($path); C::t('cache')->insert(array( 'cachekey' => $cachekey, 'cachevalue' => serialize($data), 'dateline' => $_G['timestamp'], ), false, true); } private function deleteCache($path) { $cachekey = 'qcos_uploadID_' . md5($path); C::t('cache')->delete($cachekey); } private function getPartInfo($content_range) { $arr = array(); if (!$content_range) { $arr['ispart'] = false; $arr['iscomplete'] = true; } elseif (is_array($content_range)) { $arr['ispart'] = true; $partsize = getglobal('setting/maxChunkSize'); $arr['partnum'] = ceil(($content_range[2] + 1) / $partsize); if (($content_range[2] + 1) >= $content_range[3]) { $arr['iscomplete'] = true; } else { $arr['iscomplete'] = false; } } else { return false; } return $arr; } public function uploadStream($file, $filename, $path, $relativePath, $content_range) { $data = array(); $arr = self::getPartInfo($content_range); //echo ($relativePath).'vvvvvvvv'; //if($arr['partnum']>1) print_r($arr); if ($relativePath && ($arr['iscomplete'])) { $path1 = $path; $patharr = explode('/', $relativePath); //print_r($patharr); foreach ($patharr as $key => $value) { if (!$value) { continue; } // echo $path1.'---'.$value.'------'; $re = self::CreateFolder($path1, $value); if (isset($re['error'])) { return $re; } else { if ($key == 0) { $data['icoarr'][] = $re['icoarr']; $data['folderarr'][] = $re['folderarr']; } } $path1 = $path1 . $value . '/'; } } $path .= $relativePath; if ($arr['ispart']) { if ($re1 = self::upload($file, $path, $filename, $arr)) { if ($re1['error']) { return $re1; } if ($arr['iscomplete']) { if (empty($re1['error'])) { $data['icoarr'][] = $re1; return $data; } else { $data['error'] = $re1['error']; return $data; } } else { return true; } } } else { $re1 = self::upload($file, $path, $filename); if (empty($re1['error'])) { $data['icoarr'][] = $re1; return $data; } else { $data['error'] = $re1['error']; return $data; } } } public function uploadbymulti($uploadFile, $path, $filesize = 0, $options = array()) { global $_G; $arr = self::parsePath($path); $oss= self::init($path); if (is_array($oss) && $oss['error']) return $oss; $partsize = 1024 * 1024 * 5; //分块大小5M if(is_file($uploadFile)){ $stream = $uploadFile; }else{ $stream = IO::getstream($uploadFile); } $filesize = ($filesize) ? $filesize:filesize($stream); if ($filesize < $partsize) { try { $source = fopen($stream, 'rb'); if(!$source){ return array('error'=>'file is empty '); } $result = $oss->putObject(array( 'Bucket' => $arr['bucket'], 'Key' => $arr['object'], 'Body' =>$source, )); return $result; } catch (ErrorException $e) { return array('error' => $e->getMessage()); } } else { //分片上传 $partinfo = array('ispart' => true, 'partnum' => 0, 'iscomplete' => false); if (!$handle = fopen($stream, 'rb')) { return array('error' => lang('open_file_error')); } $fileContent = ''; while (!feof($handle)) { $fileContent .= fread($handle, 8192); if (strlen($fileContent) == 0) return array('error' => lang('file_not_exist1')); if (strlen($fileContent) >= $partsize) { if ($partinfo['partnum'] * $partsize + strlen($fileContent) >= $filesize) $partinfo['iscomplete'] = true; $partinfo['partnum'] += 1; //file_put_contents($cachefile, $fileContent); if ($partinfo['partnum'] == 1){//第一个分块时 初始化分块上传得到$uploadID;并缓存住,留以后分块使用 //初始化分块 try { $response = $oss->CreateMultipartUpload(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'])); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } $upload_id = $response['UploadId']; } try { //上传分块 $response = $oss->UploadPart(array( 'Bucket' => $arr['bucket'], 'Body'=>$fileContent, 'Key' => $arr['object'], 'UploadId' => $upload_id, 'PartNumber' => $partinfo['partnum'] )); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } if ($partinfo['iscomplete']) { //获取已上传分块列表信息 try { $partlists = $oss->listParts(array( 'Bucket' => $arr['bucket'], //格式:BucketName-APPID 'Key' => $arr['object'], 'UploadId' => $upload_id, )); } catch (\Exception $e) { return array('error' => $e->getMessage()); } try{ $re = $oss->completeMultipartUpload(array( 'Bucket' => $arr['bucket'], //格式:BucketName-APPID 'Key' => $arr['object'], 'UploadId' =>$upload_id, 'Parts' =>$partlists['Parts'] )); }catch (ErrorException $e) { return array('error' => $e->getMessage()); } return $re; } $fileContent = ''; } } fclose($handle); if (!empty($fileContent)) { $partinfo['partnum'] += 1; $partinfo['iscomplete'] = true; try { //上传最后一个分块 $response = $oss->UploadPart(array( 'Bucket' => $arr['bucket'], 'Body'=>$fileContent, 'Key' => $arr['object'], 'UploadId' => $upload_id, 'PartNumber' => $partinfo['partnum'] )); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } //获取已上传分块列表信息 try { $partlists = $oss->listParts(array( 'Bucket' => $arr['bucket'], //格式:BucketName-APPID 'Key' => $arr['object'], 'UploadId' => $upload_id, )); } catch (\Exception $e) { return array('error' => $e->getMessage()); } try{ $re = $oss->completeMultipartUpload(array( 'Bucket' => $arr['bucket'], //格式:BucketName-APPID 'Key' => $arr['object'], 'UploadId' =>$upload_id, 'Parts' =>$partlists['Parts'] )); }catch (ErrorException $e) { return array('error' => $e->getMessage()); } return $re; } } } function CreateMultipartUpload($path) { $arr = self::parsePath($path); $oss = self::init($path); if (is_array($oss) && $oss['error']) return $oss; $ret = $oss->createMultipartUpload(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'])); } function upload($file, $path, $filename, $partinfo = array(), $ondup = 'overwrite') { global $_G; $path .= $filename; $arr = self::parsePath($path); try { $oss = self::init($path); if (is_array($oss) && $oss['error']) return $oss; $upload_file_options = array( 'SourceFile' => $file, ); if ($partinfo['partnum']) { $upload_file_options['PartNumber'] = $partinfo['partnum']; if ($partinfo['partnum'] == 1) {//第一个分块时 初始化分块上传得到$uploadID;并缓存住,留以后分块使用 //初始化分块 try { $response = $oss->CreateMultipartUpload(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'])); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } $upload_id = $response['UploadId']; try { //上传分块 $response = $oss->UploadPart(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'], 'UploadId' => $upload_id, 'PartNumber' => $upload_file_options)); } catch (ErrorException $e) { array('error' => $e->getMessage()); } if (md5_file($file) != strtolower(trim($response['ETag'], '"'))) { //验证上传是否完整 return array('error' => lang('upload_file_incomplete')); } $data = array(); $data['upload_id'] = $upload_id; $data['filesize'] = filesize($file); $data['partnum'] = 1; $data['path'] = $path; $data['parts'][$data['partnum']] = array( 'PartNumber' => $data['partnum'], 'ETag' => $response['ETag'] ); self::saveCache($path, $data); } else { $cache = self::getCache($path); $upload_id = $cache['upload_id']; $cache['partnum'] += 1; try { //上传分块 $response = $oss->UploadPart(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'], 'UploadId' => $upload_id, 'PartNumber' => $upload_file_options)); } catch (ErrorException $e) { array('error' => $e->getMessage()); } if (md5_file($file) != strtolower(trim($response['ETag'], '"'))) { //验证上传是否完整 return array('error' => lang('upload_file_incomplete')); } //print_r($cache); $cache['filesize'] += filesize($file); $cache['parts'][$partinfo['partnum']] = array( 'PartNumber' => $cache['partnum'], 'ETag' => $response['ETag'] ); //print_r($cache);exit('dddd'); self::saveCache($path, $cache); } if ($partinfo['iscomplete']) { $cache = self::getCache($path); try { $response = $oss->completeMultipartUpload(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'], 'UploadId' => $cache['upload_id'], 'Parts' => $cache['parts'])); } catch (ErrorException $e) { array('error' => $e->getMessage()); } self::deleteCache($path); $meta = array( 'Key' => $arr['object'], 'Size' => $cache['filesize'], 'LastModified' => $response['LastModified']->format('Y-m-d H:i:s'), ); $icoarr = self::_formatMeta($meta, $arr); return $icoarr; } else { return true; } } else { $response = $oss->putObjectBySavePath($file, $arr['object']); if ($response === false) { return array('error' => self::get_error_info($oss)); } $meta = array( 'Key' => $arr['object'], 'Size' => filesize($file), 'LastModified' => $response['LastModified'], ); $icoarr = self::_formatMeta($meta, $arr); return $icoarr; } } catch (Exception $e) { return array('error' => $e->getMessage()); } } public function rename($path, $name) {//重命名 $arr = self::parsePath($path); //判断是否为目录 $patharr = explode('/', $arr['object']); $arr['object1'] = ''; if (strrpos($path, '/') == (strlen($path) - 1)) {//是目录 return array('error' => lang('folder_not_allowed_rename')); } else { $ext = strtolower(substr(strrchr($arr['object'], '.'), 1)); foreach ($patharr as $key => $value) { if ($key >= count($patharr) - 1) break; $arr['object1'] .= $value . '/'; } $arr['object1'] .= $ext ? (preg_replace("/\.\w+$/i", '.' . $ext, $name)) : $name; } if ($arr['object'] != $arr['object1']) { $oss = self::init($path); if (is_array($oss) && $oss['error']) return $oss; $CopySource = $arr['bucket'] . '.cos.' . $this->qcos_config ['region'] . '.myqcloud.com/' . $arr['object']; try { $result = $oss->copyObject(array('Bucket' => $arr['bucket'], 'Key' => $arr['object1'], 'CopySource' => $CopySource)); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } try { $response = $oss->deleteObject(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'])); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } } return self::getMeta($arr['bz'] . $arr['bucket'] . '/' . $arr['object1']); } /** * 移动文件到目标位置 * * @param string $opath 被移动的文件路径 * @param string $path 目标位置(可能是同一api内或跨api,这两种情况分开处理) * * @return icosdatas */ public function CopyTo($opath, $path, $iscopy) { static $i = 0; $i++; $oarr = self::parsePath($opath); $arr = IO::parsePath($path); $oss = self::init($opath); if (is_array($oss) && $oss['error']) return $oss; try { $data = self::getMeta($opath); switch ($data['type']) { case 'folder'://创建目录 //exit($arr['path'].'===='.$data['name']); if ($re = IO::CreateFolder($path, $data['name'])) { if (isset($re['error']) && intval($re['error_code']) != 31061) { $data['success'] = $arr['error']; } else { $data['newdata'] = $re['icoarr']; $data['success'] = true; //echo $opath.'
'; $contents = self::listFilesAll($oss, $opath); $value = array(); foreach ($contents as $key => $value) { if ($value['path'] != $opath) { $data['contents'][$key] = self::CopyTo($value['path'], $re['folderarr']['path']); } $value = array(); } } } else { $data['success'] = 'create folder failure'; } break; default: if ($arr['bz'] == $oarr['bz']) {//同一个api时 $arr = self::parsePath($path . $data['name']); $CopySource = $arr['bucket'] . '.cos.' . $this->qcos_config ['region'] . '.myqcloud.com/' . $arr['object']; try { $result = $oss->copyObject(array('Bucket' => $arr['bucket'], 'Key' => $oarr['object'], 'CopySource' => $CopySource)); } catch (ErrorException $e) { $data['success'] = $e->getMessage(); } $meta = array( 'Key' => $arr['object'], 'Size' => $data['size'], 'LastModified' => $result['LastModified'], ); $data['newdata'] = self::_formatMeta($meta, $arr); $data['success'] = true; } else { if ($re = IO::multiUpload($opath, $path, $data['name'])) { if ($re['error']) $data['success'] = $re['error']; else { $data['newdata'] = $re; $data['success'] = true; } } } break; } } catch (Exception $e) { $data['success'] = $e->getMessage(); return $data; } return $data; } //移动缩略图到目标位置 public function moveThumbFile($path,$filepath){ $oss = self::init($path); $arr = self::parsePath($path); $brr = self::parsePath($filepath); if ($arr['bz'] == $brr['bz'] && $arr['bucket'] == $brr['bucket']) { try { $CopySource = $brr['bucket'] . '.cos.' . $this->qcos_config ['region'] . '.myqcloud.com/' . $brr['object']; $result = $oss->copyObject(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'], 'CopySource' => $CopySource, 'MetadataDirective' => 'Replaced')); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } } else { $filepath = IO::getStream($filepath); if (!$handle = fopen($filepath, 'rb')) { return array('error' => lang('open_file_error')); } $hascachfile = 0; //判断是否是文件,如果不是文件读取地址文件内容,写入缓存 if (!is_file($filepath)) { $cachefile = getglobal('setting/attachdir') . './cache/' . md5($filepath) . '.dzz'; $fileContent = ''; if (!file_exists($cachefile)) { $whandle = fopen($cachefile, 'a+'); while (!feof($handle)) { $fileContent .= fread($handle, 8192); fwrite($whandle, $fileContent); $fileContent = ''; } fclose($whandle); } if (file_exists($cachefile)) { $filepath = $cachefile; $hascachfile = 1; } } fclose($handle); $filesize = filesize($filepath); if($filesize >= 20*1024*1024){ $return = $this->uploadbymulti($filepath,$path,$filesize); if($hascachfile) @unlink($cachefile); if($return['error']) return array('error' =>$return['error']); }else{ try { $source = fopen($filepath, 'rb'); if(!$source){ return array('error'=>'file is empty '); } $result = $oss->putObject(array( 'Bucket' => $arr['bucket'], 'Key' => $arr['object'], 'Body' =>$source, )); } catch (ErrorException $e) { if($hascachfile) @unlink($cachefile); return array('error' => $e->getMessage()); } } } if($hascachfile) @unlink($cachefile); try { $result = $oss->getObjectUrl($arr['bucket'], $arr['object'], '+120 minutes'); return $result; // 请求成功 } catch (\Exception $e) { // 请求失败 return array('error' => $e->getMessage()); } } public function multiUpload($opath, $path, $filename, $attach = array(), $ondup = "newcopy") { global $_G; $partsize = 1024 * 1024 * 20; //分块大小2M if ($attach) { $data = $attach; $data['size'] = $attach['filesize']; } else { $data = IO::getMeta($opath); if ($data['error']) return $data; } $size = $data['size']; if (is_array($filepath = IO::getStream($opath))) { return array('error' => $filepath['error']); } return $this->uploadbymulti($filepath, $path . $filename, $size); } //移动文件到下载缓冲区并下载 public function moveFileToDownload($path, $filepath) { $oss = self::init($path); $arr = self::parsePath($path); $brr = self::parsePath($filepath); if ($arr['bz'] == $brr['bz'] && $arr['bucket'] == $brr['bucket']) { try { $CopySource = $brr['bucket'] . '.cos.' . $this->qcos_config ['region'] . '.myqcloud.com/' . $brr['object']; $result = $oss->copyObject(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'], 'CopySource' => $CopySource, 'MetadataDirective' => 'Replaced', 'ContentDisposition' =>'attachment')); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } } else { try { $stream = IO::getStream($filepath); $result = $oss->putObject(array( 'Bucket' => $arr['bucket'], 'Key' => $arr['object'], 'Body' => fopen($stream, 'rb'), 'ContentDisposition'=>'attachment' )); } catch (ErrorException $e) { return array('error' => $e->getMessage()); } } try { $result = $oss->getObjectUrl($arr['bucket'], $arr['object'], '+120 minutes'); return $result; // 请求成功 } catch (\Exception $e) { // 请求失败 return array('error' => $e->getMessage()); } } public function getPath($ext='', $dir = 'dzz') { global $_G; if ($ext && in_array(trim($ext, '.'), $_G['setting']['unRunExts'])) { $ext = 'dzz'; } $subdir = $subdir1 = $subdir2 = ''; $subdir1 = date('Ym'); $subdir2 = date('d'); $subdir = $subdir1 . '/' . $subdir2 . '/'; $target1 = $dir . '/' . $subdir . 'index.html'; $target = $dir . '/' . $subdir; return ($ext) ? $target . date('His') . '' . strtolower(random(16)) .'.'.$ext:$target . date('His') . '' . strtolower(random(16)); } public function getthumbpath($dir = 'dzz'){ $subdir = $subdir1 = $subdir2 = ''; $subdir1 = date('Ym'); $subdir2 = date('d'); $subdir = $subdir1 . '/' . $subdir2 . '/'; // $target1 = $dir . '/' . $subdir . 'index.html'; $target = $dir . '/' . $subdir; return $target; } public function path_info($filepath) { $path_parts = array(); $path_parts ['dirname'] = rtrim(substr($filepath, 0, strrpos($filepath, '/')),"/")."/"; $path_parts ['basename'] = ltrim(substr($filepath, strrpos($filepath, '/')),"/"); $path_parts ['extension'] = substr(strrchr($filepath, '.'), 1); $path_parts ['filename'] = ltrim(substr($path_parts ['basename'], 0, strrpos($path_parts ['basename'], '.')),"/"); return $path_parts; } //移动临时上传区域文件到上传目标位置 public function movetmpdataToattachment($path, $data) { global $_G; //获取上传的目标目录 $pathinfo = $this->path_info($data['Key']); $relativepath = $data['dirname'] ? getstr($data['dirname']):''; $pfid = $data['pfid'] ? trim($data['pfid']):''; $level = 0; //如果有不存在的目录则创建之 $datas = array(); $datas['pfid'] = trim($pfid); if ($relativepath) { $folderdata = C::t('pichome_folder')->createfolerbypath($data['appid'],$relativepath,$pfid); $pfid = $folderdata['fid']; $level = isset($folderdata['level']) ? $folderdata['level']:0; } if (!isset($data['md5'])) { $file = self::getStream($path); $data['md5'] = md5_file($file); } $filename = $pathinfo['basename']; $pathinfo = pathinfo($path); $ext = strtolower($pathinfo['extension']); $filepath = self::getPath($ext); $attachment = array( 'filesize' => $data['size'], 'attachment' =>$filepath, 'filetype' => $ext, 'filename' => $filename, 'remote' => $data['did'], 'copys' => 0, 'md5' => $data['md5'], 'unrun' => 0, 'dateline' => $_G['timestamp'], ); $topath = $data[ 'bz' ] . ':' . $data[ 'did' ] . ':' .$attachment['attachment']; $arr = self::parsePath($path); $oarr = self::parsePath($topath); if ($path != $topath) {//如果文件位置不相同则执行移动 $oss = self::init($path); if (is_array($oss) && $oss['error']) return $oss; $filename = $this->get_basename($arr['object']); //$CopySource = $this->qcos_config['schema'].'://'.$arr['bucket'] . '.cos.' . $this->qcos_config ['region'] . '.myqcloud.com/' . dirname($arr['object']).'/'.urlencode($filename); $CopySource = $arr['bucket'] . '.cos.' . $this->qcos_config ['region'] . '.myqcloud.com/' . dirname($arr['object']).'/'.urlencode($filename); try { $result = $oss->copyObject(array('Bucket' => $oarr['bucket'], 'Key' => $oarr['object'], 'CopySource' => $CopySource)); } catch (\Exception $e) { runlog('qcosupload',$CopySource.' move to folder failed'); return array('error' => $e->getMessage()); } try { $response = $oss->deleteObject(array('Bucket' => $arr['bucket'], 'Key' => $arr['object'])); } catch (\Exception $e) { runlog('qcosupload',$CopySource.' delete tmp file failed'); return array('error' => $e->getMessage()); } } //获取文件路由对应位置 if($attachment['aid'] = C::t('attachment')->insert($attachment, 1)){ $datas['icoarr'][] = self::uploadToattachment($attachment,$data['appid'],$pfid,$level); } $datas['folder'] =C::t('pichome_folder')->fetch_allfolder_by_fid($pfid); return $datas; } //兼容linux下获取文件名 public function get_basename($filename) { if ($filename) { return preg_replace('/^.+[\\\\\\/]/', '', $filename); } return ''; } public function uploadToattachment($attach, $appid,$fid,$level,$nohook=0) { global $_G; $bz = io_remote::getBzByRemoteid($attach['remote']); $path = $bz.$attach['attachment']; $imginfo = $this->getMeta($path,1); $setarr = [ 'lastdate' => TIMESTAMP * 1000, 'appid' => $appid, 'apptype' => 1, 'uid' => $_G['uid'], 'username' => $_G['username'], 'size' => $attach['filesize'], 'type' => getTypeByExt($attach['filetype']), 'ext' => $attach['filetype'], 'mtime' => TIMESTAMP * 1000, 'dateline' => TIMESTAMP * 1000, 'btime' => TIMESTAMP * 1000, 'width' => isset($imginfo['width']) ? $imginfo['width'] : 0, 'height' => isset($imginfo['height']) ? $imginfo['height'] : 0, 'lastdate' => TIMESTAMP, 'level' => $level ? $level : 0, 'name' => $attach['filename'], 'fids' => $fid ]; if ($setarr['rid'] = C::t('pichome_resources')->insert_data($setarr)) {//插入主表 C::t('pichome_vapp')->addcopy_by_appid($appid); C::t('attachment')->update($attach['aid'], array('copys' => $attach['copys'] + 1));//增加图片使用数 //属性表数据 $attrdata = [ 'rid' => $setarr['rid'], 'appid' => $appid, 'path' => $attach['aid'], 'searchval' => $setarr['name'] ]; C::t('pichome_resources_attr')->insert($attrdata); //目录数据 if($fid){ $frsetarr = ['appid' => $appid, 'rid' => $setarr['rid'], 'fid' => $fid]; C::t('pichome_folderresources')->insert($frsetarr); } }else{ return array('error'=>'upload failer'); } if ($setarr['rid']) { C::t('pichome_vapp')->update($appid,['dateline'=>TIMESTAMP]); $setarr['fsize'] = formatsize($setarr['size']); $setarr['ftype'] = getFileTypeName($setarr['type'], $setarr['ext']); $setarr['fdateline'] = dgmdate($setarr['dateline']/1000); $setarr['icondata'] = false; $setarr['width'] = ($setarr['width']) ? intval($setarr['width']):900; $setarr['height'] = ($setarr['height']) ? intval($setarr['height']):900; $setarr['realpath'] = IO::getStream('attach::'.$attach['aid']); $setarr['path'] = $path; $setarr['path'] = dzzencode($setarr['rid'], '', 0, 0); $setarr['aid'] = $attach['aid']; $setarr['addnum'] = 1; return $setarr; } else { return array('error' => lang('data_error')); } } public function getThumburl($path,$size,$thumbtype=1,$original = 0,$extparams=array(),$width = 0,$height = 0){ global $_G; $size=trim($size); $size=in_array($size,array_keys($_G['setting']['thumbsize']))?$size:'large'; if(!$width) $width=$_G['setting']['thumbsize'][$size]['width']; if(!$height) $height=$_G['setting']['thumbsize'][$size]['height']; return IO::getThumb($path,$width,$height,$original,true,$thumbtype,$extparams); } public function upload_content($path,$content){ $arr = self::parsePath($path); $qcos = self::init($path); if (is_array($qcos) && $qcos['error']) return $qcos; try { $ret = $qcos->Upload($arr['bucket'], $arr['object'],$content); return $ret; } catch (Exception $e) { return array('error' => $e->getMessage()); } } }