<?php
$dir=__FILE__;
$dir = str_replace("\\","/", $dir);
$dir=dirname($dir);
if (is_file($dir . '/php/oss-sdk-php/autoload.php')) {
    require_once $dir . '/php/oss-sdk-php/autoload.php';
}
use OSS\OssClient;
use OSS\Core\OssUtil;

error_reporting(E_ALL^E_NOTICE^E_WARNING);
$longopts = [
	"key:",
	"callback:",
	"signature:",
	"OSSAccessKeyId:",
	"policy:",
	"success_action_status::",
	"file:",
	"url:",
	"upload_id::",
    "server::",
];
$opt = getopt("shortopt",$longopts);
if(!$opt['success_action_status']){
	$opt['success_action_status'] = 200;
}
if($opt['server']){
    $yundipianUrl = trim($opt['server'],'/');
}else{
    $yundipianUrl = 'https://yundipian.com';
}

$post_data = [
	'key'=>$opt['key'],
	'callback'=>$opt['callback'],
	'signature'=>$opt['signature'],
	'OSSAccessKeyId'=>$opt['OSSAccessKeyId'],
	'policy'=>$opt['policy'],
	'success_action_status'=>$opt['success_action_status'],
    // 'x-oss-content-type'=>'image/jpeg',
	// 'file'=>new \CURLFile($opt['file']),
];
$mime = getMime($opt['key']);//OSS自动判断有时候不太准，这里按后缀名强制判断一下
if($mime){
    $post_data['x-oss-content-type'] = $mime;
}

//最后再放file字段
$post_data['file'] = new \CURLFile($opt['file']);
// $fileSize = filesize($opt['file']);
$fileSize = sprintf('%u',filesize($opt['file']));
if($fileSize >= 50 * 1000 * 1000){
	//大文件 走分片上传
	if(!$opt['upload_id']){
		echo 'Miss param:upload_id!';
		die;
	}
	$uploadFile = $opt['file'];
	$object = $opt['key'];

	$encode = mb_detect_encoding($object, array("ASCII",'UTF-8',"GB2312","GBK",'BIG5'));
	$object = iconv($encode,'utf-8',$object);
	$field = [
		'upload_id'	=> $opt['upload_id'],
		'object'	=>$object,
	];
	$init = httpRequest($yundipianUrl.'/index/tools/initiateOssMultipartUpload','POST',$field);
	if($init['code'] != 200){
		echo 'Init multipart upload error,http code:'.$init['code'];
		die;
	}
	$res = json_decode($init['response'],true);
	if($res && $res['code'] == 200){
		$aliUploadId = $res['data']['uploadId'];
		$endpoint = $res['data']['app_point'];
		$bucket = $res['data']['app_bucket'];
	}else{
		echo 'Init multipart upload response error:['.$res['code'].']'.$res['msg'];
		die;
	}
	
	$ossClient = new OssClient($opt['OSSAccessKeyId'], '88888888', $endpoint);
	$partSize = 50 * 1000 * 1000;
    $pieces = $ossClient->generateMultiuploadParts($fileSize, $partSize);
    $responseUploadPart = array();
    $uploadPosition = 0;
    $isCheckMd5 = true;
    foreach ($pieces as $i => $piece) {
        $fromPos = round($uploadPosition + (float)$piece[$ossClient::OSS_SEEK_TO]);
        $toPos = round((float)$piece[$ossClient::OSS_LENGTH] + $fromPos - 1);
        sxlog("上传分片：".$i."[".$fromPos."-".$toPos."]"."文件：".$object.";上传ID：".$aliUploadId);
        $upOptions = array(
            // 上传文件。
            $ossClient::OSS_FILE_UPLOAD => $uploadFile,
            // 设置分片号。
            $ossClient::OSS_PART_NUM => ($i + 1),
            // 指定分片上传起始位置。
            $ossClient::OSS_SEEK_TO => $fromPos,
            // 指定文件长度。
            $ossClient::OSS_LENGTH => $toPos - $fromPos + 1,
            // 是否开启MD5校验，true为开启。
            $ossClient::OSS_CHECK_MD5 => $isCheckMd5,
            'yundipian_url'=>$yundipianUrl,
            'yundipian_upload_id'=>$opt['upload_id'],
        );
        // 开启MD5校验。
        if ($isCheckMd5) {
            $contentMd5 = OssUtil::getMd5SumForFile($uploadFile, $fromPos, $toPos);
            $upOptions[$ossClient::OSS_CONTENT_MD5] = $contentMd5;
        }
        try {
            // 上传分片。
            $responseUploadPart[] = $ossClient->uploadPart($bucket, $object, $aliUploadId, $upOptions);
            // textlog('upload['.$aliUploadId.']:'.$piece['seekTo'].',length:'.$piece['length']);
            $toPos++;
            // echo $opt['upload_id'].'-'.$aliUploadId.'-'.$toPos.'/'.$fileSize."\r\n";
        } catch(\Exception $e) {
            printf($e->getMessage() . "\n");
            return;
        }
    }
    $uploadParts = array();
    foreach ($responseUploadPart as $i => $eTag) {
        $uploadParts[] = array(
            'PartNumber' => ($i + 1),
            'ETag' => $eTag,
        );
    }
    $uploadParts = yundipian_encrypt(json_encode($uploadParts),'^client^');
    $field = [
    	'upload_id'=>$opt['upload_id'],
    	'upload_parts'=>$uploadParts,
    	'ali_upload_id'=>$aliUploadId,
    	'object'=>$object,

    ];
    $end = httpRequest($yundipianUrl.'/index/tools/endMultipartUpload','POST',$field);
    if($end['code'] != 200){
    	echo 'Upload end error code:'.$end['code'];
    	die;
    }else{
    	$endRes = json_decode($end['response'],true);
    	if($endRes['code'] != 200){
    		echo 'Upload end error['.$endRes['code'].']'.$endRes['msg'];
    		die;
    	}
    }
    /*
    
    try {
    	$upOptions = [
    		'yundipian_url'=>$yundipianUrl,
        	'yundipian_upload_id'=>$opt['upload_id'],
    	];
        // 执行completeMultipartUpload操作时，需要提供所有有效的$uploadParts。OSS收到提交的$uploadParts后，会逐一验证每个分片的有效性。当所有的数据分片验证通过后，OSS将把这些分片组合成一个完整的文件。
        $ossClient->completeMultipartUpload($bucket, $object, $aliUploadId, $uploadParts,$upOptions);
    }  catch(OssException $e) {
        printf($e->getMessage() . "\n");
        return;
    }
    //*/
    echo json_encode(array("Status"=>"Ok"));
    die;
}
$ch = curl_init();
$encode = mb_detect_encoding($post_data['key'], array("ASCII",'UTF-8',"GB2312","GBK",'BIG5'));
$post_data['key'] = iconv($encode,'utf-8',$post_data['key']);
//$str_encode = mb_convert_encoding($post_data['key'], $encode,'UTF-8'); 
//$url =  $opt['url'];//'http://securebox.oss-cn-beijing.aliyuncs.com';
curl_setopt($ch, CURLOPT_URL, $opt['url']);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
$ssl = preg_match('/^https:\/\//i',$opt['url']) ? TRUE : FALSE;
if($ssl){
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在
}
$output = curl_exec($ch);
$info = curl_getinfo($ch);
$error = curl_error($ch);
curl_close($ch);
if($info['http_code'] == 0){
	echo "{\"Status\": \"http_code error0\"}";
}else{
	echo $output;
}
function getFileType ($key){
    $fileArr = explode("/",$key);
    $name = $fileArr[count($fileArr) - 1];
    if(strrpos($name,".") === false) return "";
    $ext = substr($name,strrpos($name,".") + 1);
    return $ext;
}
function getMime($key){
    $type = getFileType($key);
    switch($type){
        case "jpg":
        case "jpeg":
            return "image/jpeg";
        case "png":
            return "image/png";
        case "gif":
            return "image/gif";
        case "mp4":
            return "video/mp4";
        default:
            return "";
    }
}
function httpRequest($url, $method="GET", $postfields = null, $headers = array(), $debug = false,$timeout=10) {
    $method = strtoupper($method);
    $ci = curl_init();
    /* Curl settings */
    curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
    curl_setopt($ci, CURLOPT_USERAGENT, "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/61.0.3163.100 Safari/537.36");
    curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, $timeout); /* 在发起连接前等待的时间，如果设置为0，则无限等待 */
    curl_setopt($ci, CURLOPT_TIMEOUT, $timeout); /* 设置cURL允许执行的最长秒数 */
    curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
    switch ($method) {
        case "POST":
            curl_setopt($ci, CURLOPT_POST, true);
            if (!empty($postfields)) {
                $tmpdatastr = is_array($postfields) ? http_build_query($postfields) : $postfields;
                curl_setopt($ci, CURLOPT_POSTFIELDS, $tmpdatastr);
            }
            break;
        default:
            curl_setopt($ci, CURLOPT_CUSTOMREQUEST, $method); /* //设置请求方式 */
            break;
    }
    $ssl = preg_match('/^https:\/\//i',$url) ? TRUE : FALSE;
    curl_setopt($ci, CURLOPT_URL, $url);
    if($ssl){
        curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE); // https请求 不验证证书和hosts
        curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE); // 不从证书中检查SSL加密算法是否存在
    }
    //curl_setopt($ci, CURLOPT_HEADER, true); /*启用时会将头文件的信息作为数据流输出*/
    curl_setopt($ci, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ci, CURLOPT_MAXREDIRS, 2);/*指定最多的HTTP重定向的数量，这个选项是和CURLOPT_FOLLOWLOCATION一起使用的*/
    curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ci, CURLINFO_HEADER_OUT, true);
    /*curl_setopt($ci, CURLOPT_COOKIE, $Cookiestr); * *COOKIE带过去** */
    $response = curl_exec($ci);
    $requestinfo = curl_getinfo($ci);
    $http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);
    if ($debug) {
        echo "=====post data======\r\n";
        var_dump($postfields);
        echo "=====info===== \r\n";
        print_r($requestinfo);
        echo "=====response=====\r\n";
        print_r($response);
    }
    curl_close($ci);
    // return $response;
	return array('code'=>$http_code, 'response'=>$response,'request'=>$requestinfo);
}

function yundipian_encrypt($data, $key = '', $expire = 0) {
    $key  = md5($key);
    $data = base64_encode($data);
    $x    = 0;
    $len  = strlen($data);
    $l    = strlen($key);
    $char = '';

    for ($i = 0; $i < $len; $i++) {
        if ($x == $l) $x = 0;
        $char .= substr($key, $x, 1);
        $x++;
    }

    $str = sprintf('%010d', $expire ? $expire + time():0);

    for ($i = 0; $i < $len; $i++) {
        $str .= chr(ord(substr($data, $i, 1)) + (ord(substr($char, $i, 1)))%256);
    }
    return str_replace(array('+','/','='),array('-','_',''),base64_encode($str));
}

function sxlog($str,$level=10,$module=''){
    global $dir;
    $write = false;
    if($level < 10){
        $write = true;
    }else{
        $write = config('app_debug')?true:false;
    }
    if($write){
        if (strtoupper(substr(php_uname(),0,3)) == 'WIN') {
            $str = iconv("UTF-8","GB2312//IGNORE",$str);
        }
        switch ($level) {
            case 10:
                $str = 'INFO'."\t".$str;
                break;
            case 2:
                $str = 'WARING'."\t".$str;
                break;
            case 1:
                $str = 'ERROR'."\t".$str;
                break;
            default:
                # code...
                break;
        }
        if(!defined("DS")){
            define("DS",DIRECTORY_SEPARATOR);
        }
        $path = $dir.DS.'Logs'.DS."php".DS;
        if(!file_exists($path) || !is_dir($path)){
            @mkdir($path,0777,true);
        }
        if(!$module){
            $module = IS_CLI?'cli':'common';
        }
        $module = date('Ymd').'-'.$module;
        file_put_contents($path.$module.".log",date('Y-m-d H:i:s')."\t".$str."\r\n",FILE_APPEND);
        unset($str);
    }
}