3684e8e638d74e9f1b285fa0d0f1f4ef01641ba4.svn-base 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521
  1. <?php
  2. /**
  3. * 七牛处理驱动
  4. *
  5. * @author widuu <admin@widuu.com>
  6. * @document https://github.com/widuu/qiniu_ueditor_1.4.3
  7. */
  8. class QiniuDriver{
  9. private $qiniu_rsf_host = 'http://rsf.qbox.me';
  10. private $qiniu_rs_host = 'http://rs.qbox.me';
  11. private $qiniu_up_host = 'http://up.qiniu.com';
  12. private $qiniu_io_host = 'http://iovip.qbox.me';
  13. private $status_code = '';
  14. public function __construct($config){
  15. foreach ($config as $k => $v) {
  16. $this->$k = $v;
  17. }
  18. }
  19. /**
  20. * 用于直传的时候获取token的方法
  21. *
  22. * @author widuu <admin@widuu.com>
  23. */
  24. public function getToken(){
  25. $token = $this->getUploadToken($_POST['key']);
  26. return array(
  27. 'state' => 'SUCCESS',
  28. 'token' => $token
  29. );
  30. }
  31. /**
  32. * 七牛删除文件方法
  33. *
  34. * @author widuu <admin@widuu.com>
  35. */
  36. public function removeFile($file){
  37. $file = trim($this->escapeQuotes($file));
  38. $scope = $this->SafeBase64Encode("{$this->bucket}:{$file}");
  39. $url = $this->qiniu_rs_host . "/delete/" . $scope;
  40. $token = $this->getSign("/delete/".$scope."\n");
  41. $response = $this->request($url, 'POST', array('Authorization'=>"QBox $token"));
  42. if( isset($response['error']) ){
  43. return array( 'code'=> 1 ,'error' => $response['error'] );
  44. }
  45. return array( 'code'=> 0 );
  46. }
  47. /**
  48. * 七牛远程获取文件
  49. * @param string $image_url 抓取的url
  50. * @param array $ue_config ueditor 配置信息
  51. * @return array
  52. * @author widuu <admin@widuu.com>
  53. */
  54. public function fetchFile( $image_url,$ue_config ){
  55. //重组第三方拉取URL
  56. $io_host = $this->uploadQiniuUrl;
  57. $io_host = str_replace("qiniu.com", "qbox.me", $io_host);
  58. $io_host = str_replace("up", "iovip", $io_host);
  59. // 要抓取的URL
  60. $image_url = trim($image_url);
  61. // 解析Url中的Path然后根据Path获取文件名称
  62. $file_path = parse_url($image_url,PHP_URL_PATH);
  63. // 获取存储文件名的field_name
  64. $field_name = pathinfo($file_path,PATHINFO_FILENAME).'.'.pathinfo($file_path,PATHINFO_EXTENSION);
  65. // 文件名称
  66. $file_name = $this->getFileName($field_name,$ue_config,true);
  67. // 七牛抓取存储文件的 EncodedEntryURI
  68. $encoded_entry_uri = $this->SafeBase64Encode("{$this->bucket}:{$file_name}");
  69. // 七牛抓取存储文件的 EncodedURL
  70. $encoded_uri = $this->SafeBase64Encode($image_url);
  71. // 七牛POST的PATH地址
  72. $post_path = "/fetch/". $encoded_uri ."/to/". $encoded_entry_uri;
  73. // POST URL
  74. $url = $io_host . $post_path;
  75. // 抓取Token
  76. $token = $this->getSign($post_path."\n");
  77. // 返回数据
  78. $response = $this->request($url, 'POST', array('Authorization'=>"QBox $token"));
  79. // 如果有错误信息
  80. if( !empty($response['error']) ){
  81. return array(
  82. 'state' => $response['error'],
  83. "url" => $image_url,
  84. );
  85. }
  86. // 拼接上传到七牛的地址
  87. $url = trim($this->host , "/" ). "/" . trim($response['key'], "/" );
  88. // 返回抓取结果
  89. return array(
  90. "state" => "SUCCESS",
  91. "url" => $url,
  92. "size" => $response['fsize'],
  93. );
  94. }
  95. /**
  96. * 七牛合成文件的方法
  97. * @param array 合成文件信息
  98. * @return array
  99. * @author widuu <admin@widuu.com>
  100. */
  101. public function Synthesis( $params = array(),$ue_config ){
  102. $ctx_list = rtrim($_POST['ctx'],",");
  103. $file_type = trim($_POST['type']);
  104. $file_size = trim($_POST['size']);
  105. $field_name = trim($_POST['name']);
  106. $upload_url = trim($_POST['host']);
  107. $file_name = $this->getFileName($field_name,$ue_config,true);
  108. $path = '/mkfile/'.intval($file_size).'/key/'.$this->SafeBase64Encode($file_name);
  109. $path .= '/mimeType/'.$this->SafeBase64Encode($file_type);
  110. $headers = array(
  111. 'Content-Type' => "text/plain",
  112. 'Authorization' => "UpToken ".$this->getUploadToken($file_name),
  113. );
  114. $response = $this->request($upload_url.$path, 'POST', $headers, $ctx_list);
  115. return array(
  116. "state" => $response['state'],
  117. "url" => $response['url'],
  118. "type" => $_POST['type'],
  119. "size" => $response['size'],
  120. "original" => $_POST['name']
  121. );
  122. }
  123. /**
  124. * 设置上传信息
  125. *
  126. * @param array $config ueditor php配置信息
  127. * @param array $ue_config ueditor json配置信息
  128. * @return array
  129. * @author widuu <admin@widuu.com>
  130. */
  131. public function getFileInfo( $config ,$ue_config ){
  132. $file_info = $this->setUploadInfo($config, $ue_config );
  133. $result = $this->uploadFile($file_info,$ue_config);
  134. // 如果有错误信息
  135. if( !empty($result['error']) ){
  136. return array(
  137. 'state' => $result['error']
  138. );
  139. }
  140. // 返回上传信息
  141. $field_name = $config['fieldName'];
  142. return array(
  143. "state" => "SUCCESS",
  144. "url" => $result['url'],
  145. "title" => $result['name'],
  146. "original" => $_FILES[$field_name]['name'],
  147. "type" => $_FILES[$field_name]['type'],
  148. "size" => $_FILES[$field_name]['size'],
  149. );
  150. }
  151. /**
  152. * 七牛列出文件列表
  153. *
  154. * @param prefix 前缀
  155. * @param marker 标记
  156. * @param limit 限制出现的个数
  157. * @author widuu <admin@widuu.com>
  158. */
  159. public function getList( $prefix, $marker, $limit){
  160. $request_info = $this->getListRequestInfo( $prefix, $marker, $limit );
  161. $request_url = $request_info['path'];
  162. $request_token = $request_info['token'];
  163. $response = $this->request($request_url, 'POST', array('Authorization'=>"QBox {$request_token}"));
  164. return $response;
  165. }
  166. /**
  167. * 设置上传信息
  168. *
  169. * @param array $config ueditor php配置信息
  170. * @param array $ue_config ueditor json配置信息
  171. * @return array
  172. * @author widuu <admin@widuu.com>
  173. */
  174. public function setUploadInfo( $config, $ue_config ){
  175. $field_name = $config['fieldName'];
  176. $file_name = $this->getFileName($field_name,$ue_config);
  177. $upload_info = array(
  178. "name" => 'file',
  179. 'file_name' => $file_name,
  180. 'file_body' => file_get_contents($_FILES[$field_name]['tmp_name'])
  181. );
  182. if( $config['base64'] == "base64" ){
  183. $upload_info['file_name'] = $file_name.'png';
  184. $upload_info['file_body'] = base64_decode( $_POST[$field_name] );
  185. }
  186. return $upload_info;
  187. }
  188. /**
  189. * 获取文件名称
  190. *
  191. * @param string $field_name 文件的filedname或者远程url地址
  192. * @param array $ue_config ueditor json配置信息
  193. * @param array $flag false 上传文件|true 远程抓取
  194. * @return string
  195. * @author widuu <admin@widuu.com>
  196. */
  197. public function getFileName( $field_name ,$ue_config , $flag = false ){
  198. $prefix = trim($ue_config['qiniuUploadPath'] , "/" ) . "/" ;
  199. $format = $ue_config['qiniuDatePath'];
  200. $time = explode('-', date("Y-y-m-d",time()));
  201. $file_name = "";
  202. if( !empty($format) ){
  203. if( strpos($format, 'y') !== false ){
  204. $format = str_replace("yyyy", $time[0], $format);
  205. $format = str_replace("yy" , $time[1], $format);
  206. }
  207. $format = str_replace("mm", $time[2], $format);
  208. $format = str_replace("dd", $time[3], $format);
  209. }
  210. if( isset($this->save_type) && trim($this->save_type) == 'date' ){
  211. // 不是远程抓取的时候
  212. if( !$flag ){
  213. $save_name = pathinfo($_FILES[$field_name]["name"], PATHINFO_EXTENSION);
  214. }else{
  215. $save_name = pathinfo($field_name, PATHINFO_EXTENSION);
  216. }
  217. $file_name = $prefix . $format.'/'.time().mt_rand(0,10).'.'.$save_name;
  218. }else{
  219. // 不是远程抓取
  220. if( !$flag ){
  221. $save_name = $_FILES[$field_name]["name"];
  222. }else{
  223. $file_name = $field_name;
  224. }
  225. $file_name = $prefix . $format . '/' . $save_name;
  226. }
  227. return $file_name;
  228. }
  229. /**
  230. * 上传文件到七牛的方法
  231. *
  232. * @param array $upload_info 上传文件信息
  233. * @return array
  234. * @author widuu <admin@widuu.com>
  235. */
  236. public function uploadFile( $upload_info,$ue_config ){
  237. $token = $this->getUploadToken($upload_info['file_name']);
  238. $mimeBoundary = md5(microtime());
  239. $header = array('Content-Type'=>'multipart/form-data;boundary='.$mimeBoundary);
  240. $data = array();
  241. $fields = array(
  242. 'token' => $token,
  243. 'key' => $upload_info['file_name'],
  244. );
  245. foreach ($fields as $name => $val) {
  246. array_push($data, '--' . $mimeBoundary);
  247. array_push($data, "Content-Disposition: form-data; name=\"$name\"");
  248. array_push($data, '');
  249. array_push($data, $val);
  250. }
  251. //文件
  252. array_push($data, '--' . $mimeBoundary);
  253. $name = $upload_info['name'];
  254. $fileName = $upload_info['file_name'];
  255. $fileBody = $upload_info['file_body'];
  256. $fileName = $this->escapeQuotes($fileName);
  257. array_push($data, "Content-Disposition: form-data; name=\"$name\"; filename=\"$fileName\"");
  258. array_push($data, 'Content-Type: application/octet-stream');
  259. array_push($data, '');
  260. array_push($data, $fileBody);
  261. array_push($data, '--' . $mimeBoundary . '--');
  262. array_push($data, '');
  263. $body = implode("\r\n", $data);
  264. $qiniuuphost = isset($this->uploadQiniuUrl) ? $this->uploadQiniuUrl : $this->qiniu_up_host;
  265. $response = $this->request($qiniuuphost, 'POST', $header, $body);
  266. return $response;
  267. }
  268. /**
  269. * 设置七牛列出文件的请求信息
  270. *
  271. * @param string $prefix 前缀
  272. * @param string $marker 标记
  273. * @param int $limit 限制出现的个数
  274. * @author widuu <admin@widuu.com>
  275. */
  276. private function getListRequestInfo($prefix='', $marker='', $limit = 0){
  277. $query = array( 'bucket' => $this->bucket );
  278. if (!empty($prefix)) {
  279. $query['prefix'] = $prefix;
  280. }
  281. if (!empty($marker)) {
  282. $query['marker'] = $marker;
  283. }
  284. if (!empty($limit)) {
  285. $query['limit'] = $limit;
  286. }
  287. $url = '/list?' . http_build_query($query);
  288. return array(
  289. 'path' => $this->qiniu_rsf_host . $url,
  290. 'token' => $this->getSign($url."\n")
  291. );
  292. }
  293. /**
  294. * 七牛Sign方法
  295. *
  296. * @param string $sign_data 加密字符串
  297. * @author widuu <admin@widuu.com>
  298. */
  299. private function getSign( $sign_data ){
  300. $sign = hash_hmac('sha1',$sign_data, $this->secret_key, true);
  301. $result = $this->access_key . ':' . $this->SafeBase64Encode($sign);
  302. return $result;
  303. }
  304. /**
  305. * 直传水印url拼接方式
  306. *
  307. * @author widuu <admin@widuu.com>
  308. */
  309. private function getDirectReturnBody(){
  310. //使用水印和非使用水印拼接方法
  311. if( !$this->use_water ){
  312. $url = trim($this->host , "/")."/$(key)";
  313. }else{
  314. $water_image = $this->SafeBase64Encode($this->water_url);
  315. $url = trim($this->host , "/")."/$(key)?watermark/1/image/{$water_image}";
  316. $url .= "/dissolve/{$this->dissolve}/gravity/{$this->gravity}/dx/{$this->dx}/dy/{$this->dy}";
  317. }
  318. $return_body = array(
  319. "url" => $url,
  320. "state" => "SUCCESS",
  321. "name" => "$(fname)",
  322. "size" => "$(fsize)",
  323. "w" => "$(imageInfo.width)",
  324. "h" => "$(imageInfo.height)",
  325. );
  326. return json_encode($return_body);
  327. }
  328. /**
  329. * 七牛base64方法
  330. *
  331. * @param string $infomation base64的字符串
  332. * @author widuu <admin@widuu.com>
  333. */
  334. private function SafeBase64Encode( $infomation ){
  335. $find = array('+', '/');
  336. $replace = array('-', '_');
  337. return str_replace($find, $replace, base64_encode($infomation));
  338. }
  339. /**
  340. * 获取上传的文件token
  341. *
  342. * @param string $key 文件名称
  343. * @return string
  344. * @author widuu <admin@widuu.com>
  345. */
  346. private function getUploadToken($key){
  347. $time = time() + $this->timeout;
  348. $scope = $this->bucket.":".$this->escapeQuotes($key);
  349. $put_policy = array(
  350. 'returnBody' => $this->getDirectReturnBody(),
  351. 'deadline' => $time,
  352. 'scope' => $scope
  353. );
  354. $safe_data = $this->SafeBase64Encode(json_encode($put_policy));
  355. return $this->getSign($safe_data).':'.$safe_data;
  356. }
  357. /**
  358. * 请求云服务器
  359. * @param string $path 请求的PATH
  360. * @param string $method 请求方法
  361. * @param array $headers 请求header
  362. * @param resource $body 上传文件资源
  363. * @return boolean
  364. */
  365. private function request($path, $method, $headers = null, $body = null){
  366. $ch = curl_init($path);
  367. $_headers = array('Expect:');
  368. if (!is_null($headers) && is_array($headers)){
  369. foreach($headers as $k => $v) {
  370. array_push($_headers, "{$k}: {$v}");
  371. }
  372. }
  373. $length = 0;
  374. $date = gmdate('D, d M Y H:i:s \G\M\T');
  375. if (!is_null($body)) {
  376. if(is_resource($body)){
  377. fseek($body, 0, SEEK_END);
  378. $length = ftell($body);
  379. fseek($body, 0);
  380. array_push($_headers, "Content-Length: {$length}");
  381. curl_setopt($ch, CURLOPT_INFILE, $body);
  382. curl_setopt($ch, CURLOPT_INFILESIZE, $length);
  383. } else {
  384. $length = @strlen($body);
  385. array_push($_headers, "Content-Length: {$length}");
  386. curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
  387. }
  388. } else {
  389. array_push($_headers, "Content-Length: {$length}");
  390. }
  391. array_push($_headers, "Date: {$date}");
  392. curl_setopt($ch, CURLOPT_HTTPHEADER, $_headers);
  393. curl_setopt($ch, CURLOPT_TIMEOUT, $this->timeout);
  394. curl_setopt($ch, CURLOPT_HEADER, 1);
  395. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  396. curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 0);
  397. curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
  398. if ($method == 'PUT' || $method == 'POST') {
  399. curl_setopt($ch, CURLOPT_POST, 1);
  400. } else {
  401. curl_setopt($ch, CURLOPT_POST, 0);
  402. }
  403. if ($method == 'HEAD') {
  404. curl_setopt($ch, CURLOPT_NOBODY, true);
  405. }
  406. $response = curl_exec($ch);
  407. if( !$response ){
  408. return false;
  409. }
  410. $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  411. curl_close($ch);
  412. list($header, $body) = explode("\r\n\r\n", $response, 2);
  413. return $this->response($body);
  414. }
  415. /**
  416. * 获取响应数据
  417. * @param string $text 响应头字符串
  418. * @return array 响应数据列表
  419. */
  420. private function response($text){
  421. $headers = explode(PHP_EOL, $text);
  422. $items = array();
  423. foreach($headers as $header) {
  424. $header = trim($header);
  425. if(strpos($header, '{') !== False){
  426. $items = json_decode($header, 1);
  427. break;
  428. }
  429. }
  430. return $items;
  431. }
  432. /**
  433. * 特殊字符串处理
  434. * @param string $str
  435. * @author widuu <admin@widuu.com>
  436. */
  437. private function escapeQuotes($str){
  438. $find = array("\\", "\"");
  439. $replace = array("\\\\", "\\\"");
  440. return str_replace($find, $replace, $str);
  441. }
  442. }