BaseUpload.php 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457
  1. <?php
  2. // +----------------------------------------------------------------------
  3. // | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
  4. // +----------------------------------------------------------------------
  5. // | Copyright (c) 2016~2023 https://www.crmeb.com All rights reserved.
  6. // +----------------------------------------------------------------------
  7. // | Licensed CRMEB并不是自由软件,未经许可不能去掉CRMEB相关版权
  8. // +----------------------------------------------------------------------
  9. // | Author: CRMEB Team <admin@crmeb.com>
  10. // +----------------------------------------------------------------------
  11. namespace crmeb\services\upload;
  12. use crmeb\basic\BaseStorage;
  13. use think\facade\Config;
  14. /**
  15. * Class BaseUpload
  16. * @package crmeb\basic
  17. */
  18. abstract class BaseUpload extends BaseStorage
  19. {
  20. /**
  21. * 缩略图
  22. * @var string[]
  23. */
  24. // protected $thumb = ['thumb_big', 'thumb_mid', 'thumb_small','thumb_water_big', 'thumb_water_mid', 'thumb_water_small'];
  25. protected $thumb = ['big', 'mid', 'small'];
  26. /**
  27. * 缩略图配置
  28. * @var array
  29. */
  30. protected $thumbConfig = [
  31. 'thumb_big_height' => 800,
  32. 'thumb_big_width' => 800,
  33. 'thumb_mid_height' => 300,
  34. 'thumb_mid_width' => 300,
  35. 'thumb_small_height' => 100,
  36. 'thumb_small_width' => 100
  37. ];
  38. /**
  39. * 水印配置
  40. * @var array
  41. */
  42. protected $waterConfig = [
  43. 'image_watermark_status' => 0,
  44. 'watermark_type' => 1,
  45. 'watermark_image' => '',
  46. 'watermark_opacity' => 0,
  47. 'watermark_position' => 1,
  48. 'watermark_rotate' => 0,
  49. 'watermark_text' => '',
  50. 'watermark_text_angle' => "",
  51. 'watermark_text_color' => '#000000',
  52. 'watermark_text_size' => '5',
  53. 'watermark_text_font' => '',
  54. 'watermark_x' => 0,
  55. 'watermark_y' => 0
  56. ];
  57. /**
  58. * 图片信息
  59. * @var array
  60. */
  61. protected $fileInfo;
  62. /**
  63. * 上传缩略图开启
  64. */
  65. protected $image_thumb_status;
  66. /**
  67. * 下载图片信息
  68. */
  69. protected $downFileInfo;
  70. /**
  71. * 要生成缩略图、水印的图片地址
  72. * @var string
  73. */
  74. protected $filePath;
  75. /**
  76. * 验证配置
  77. * @var string
  78. */
  79. protected $validate;
  80. /**
  81. * 保存路径
  82. * @var string
  83. */
  84. protected $path = '';
  85. /**
  86. * 是否自动裁剪
  87. * @var bool
  88. */
  89. protected $authThumb = true;
  90. protected function initialize(array $config)
  91. {
  92. $this->fileInfo = $this->downFileInfo = new \StdClass();
  93. $thumbConfig = $this->thumbConfig;
  94. $config['thumb'] = $config['thumb'] ?? [];
  95. $this->thumbConfig = $config['thumb'] ?? [];
  96. foreach ($config['thumb'] as $item) {
  97. if ($item == '' || $item == 0) {
  98. $this->thumbConfig = $thumbConfig;
  99. }
  100. }
  101. $this->image_thumb_status = $config['image_thumb_status'];
  102. $this->waterConfig = array_merge($this->waterConfig, $config['water'] ?? []);
  103. }
  104. /**
  105. * 设置处理缩略图、水印图片路径
  106. * @param string $filePath
  107. * @return $this
  108. */
  109. public function setFilepath(string $filePath)
  110. {
  111. $this->filePath = substr($filePath, 0, 1) === '.' ? substr($filePath, 1) : $filePath;
  112. return $this;
  113. }
  114. /**
  115. * 是否自动裁剪
  116. * @param bool $auth
  117. * @return $this
  118. */
  119. public function setAuthThumb(bool $auth)
  120. {
  121. $this->authThumb = $auth;
  122. return $this;
  123. }
  124. /**
  125. * 上传文件路径
  126. * @param string $path
  127. * @return $this
  128. */
  129. public function to(string $path)
  130. {
  131. $this->path = $path;
  132. return $this;
  133. }
  134. /**
  135. * 获取文件信息
  136. * @return array
  137. */
  138. public function getFileInfo()
  139. {
  140. return $this->fileInfo;
  141. }
  142. /**
  143. * 检测是否是图片
  144. * @param $filePath
  145. * @return bool
  146. */
  147. protected function checkImage($filePath)
  148. {
  149. //获取图像信息
  150. $info = @getimagesize($filePath);
  151. //检测图像合法性
  152. if (false === $info || (IMAGETYPE_GIF === $info[2] && empty($info['bits']))) {
  153. return false;
  154. }
  155. return true;
  156. }
  157. /**
  158. * 验证合法上传域名
  159. * @param string $url
  160. * @return string
  161. */
  162. protected function checkUploadUrl(string $url)
  163. {
  164. if ($url && strstr($url, 'http') === false) {
  165. $url = 'http://' . $url;
  166. }
  167. return $url;
  168. }
  169. /**
  170. * 获取系统配置
  171. * @return mixed
  172. */
  173. protected function getConfig()
  174. {
  175. $config['filesize'] = Config::get($this->configFile . '.filesize', []);
  176. $config['fileExt'] = Config::get($this->configFile . '.fileExt', []);
  177. $config['fileMime'] = Config::get($this->configFile . '.fileMime', []);
  178. return $config;
  179. }
  180. /**
  181. * 设置验证规则
  182. * @param array|null $validate
  183. * @return $this
  184. */
  185. public function validate(?array $validate = null)
  186. {
  187. if (is_null($validate)) {
  188. $validate = $this->getConfig();
  189. }
  190. $this->validate = $validate;
  191. return $this;
  192. }
  193. /**
  194. * 验证目录是否正确
  195. * @param string $key
  196. * @return false|string
  197. */
  198. protected function getUploadPath(string $key)
  199. {
  200. $path = ($this->path ? $this->path . '/' : '') . $key;
  201. if ($path && $path[0] === '/') {
  202. $path = substr($path, 1);
  203. }
  204. return $path;
  205. }
  206. /**
  207. * 提取文件名
  208. * @param string $path
  209. * @param string $ext
  210. * @return string
  211. */
  212. protected function saveFileName(string $path = null, string $ext = 'jpg')
  213. {
  214. return ($path ? substr(md5($path), 0, 5) : '') . date('YmdHis') . rand(0, 9999) . '.' . $ext;
  215. }
  216. /**
  217. * 提取文件后缀以及之前部分
  218. * @param string $path
  219. * @return false|string[]
  220. */
  221. protected function getFileName(string $path)
  222. {
  223. $_empty = ['', ''];
  224. if (!$path) return $_empty;
  225. if (strpos($path, '?')) {
  226. $_tarr = explode('?', $path);
  227. $path = trim($_tarr[0]);
  228. }
  229. $arr = explode('.', $path);
  230. if (!is_array($arr) || count($arr) <= 1) return $_empty;
  231. $ext_name = trim($arr[count($arr) - 1]);
  232. $ext_name = !$ext_name ? 'jpg' : $ext_name;
  233. return [explode('.' . $ext_name, $path)[0], $ext_name];
  234. }
  235. /**
  236. * 获取图片地址
  237. * @param string $filePath
  238. * @param bool $is_parse_url
  239. * @return string
  240. */
  241. protected function getFilePath(string $filePath = '', bool $is_parse_url = false)
  242. {
  243. $path = $filePath ?: $this->filePath;
  244. if ($is_parse_url) {
  245. $data = parse_url($path);
  246. //远程地址处理
  247. if (isset($data['host']) && isset($data['path'])) {
  248. if (file_exists(app()->getRootPath() . 'public' . $data['path'])) {
  249. $path = $data['path'];
  250. }
  251. }
  252. }
  253. return $path;
  254. }
  255. /**
  256. * 获取文件类型和大小
  257. * @param string $url
  258. * @param bool $isData
  259. * @return array
  260. */
  261. protected function getFileHeaders(string $url, $isData = true)
  262. {
  263. stream_context_set_default(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false]]);
  264. $header['size'] = 0;
  265. $header['type'] = 'image/jpeg';
  266. if (!$isData) {
  267. return $header;
  268. }
  269. try {
  270. $headerArray = get_headers(str_replace('\\', '/', $url), true);
  271. if (!isset($headerArray['Content-Length'])) {
  272. $header['size'] = 0;
  273. }
  274. if (!isset($headerArray['Content-Type'])) {
  275. $header['type'] = 'image/jpeg';
  276. }
  277. if (is_array($headerArray['Content-Length']) && count($headerArray['Content-Length']) == 2) {
  278. $header['size'] = $headerArray['Content-Length'][1];
  279. }
  280. if (is_array($headerArray['Content-Type']) && count($headerArray['Content-Type']) == 2) {
  281. $header['type'] = $headerArray['Content-Type'][1];
  282. }
  283. } catch (\Exception $e) {
  284. }
  285. return $header;
  286. }
  287. /**
  288. * 获取上传信息
  289. * @return array
  290. */
  291. public function getUploadInfo()
  292. {
  293. if (isset($this->fileInfo->filePath)) {
  294. if (strstr($this->fileInfo->filePath, 'http') === false) {
  295. $url = request()->domain() . $this->fileInfo->filePath;
  296. } else {
  297. $url = $this->fileInfo->filePath;
  298. }
  299. $headers = $this->getFileHeaders($url);
  300. return [
  301. 'name' => $this->fileInfo->fileName,
  302. 'real_name' => $this->fileInfo->realName ?? '',
  303. 'size' => $headers['size'] ?? 0,
  304. 'type' => $headers['type'] ?? 'image/jpeg',
  305. 'dir' => $this->fileInfo->filePath,
  306. 'thumb_path' => $this->fileInfo->filePath,
  307. 'thumb_path_big' => $this->fileInfo->filePathBig ?? '',
  308. 'thumb_path_mid' => $this->fileInfo->filePathMid ?? '',
  309. 'thumb_path_small' => $this->fileInfo->filePathSmall ?? '',
  310. 'thumb_path_water' => $this->fileInfo->filePathWater ?? '',
  311. 'time' => time(),
  312. ];
  313. } else {
  314. return [];
  315. }
  316. }
  317. /**
  318. * 获取下载信息
  319. * @return array
  320. */
  321. public function getDownloadInfo()
  322. {
  323. if (isset($this->downFileInfo->downloadFilePath)) {
  324. if (strstr($this->downFileInfo->downloadFilePath, 'http') === false) {
  325. $url = request()->domain() . $this->downFileInfo->downloadFilePath;
  326. } else {
  327. $url = $this->downFileInfo->downloadFilePath;
  328. }
  329. $headers = $this->getFileHeaders($url);
  330. return [
  331. 'name' => $this->downFileInfo->downloadFileName,
  332. 'real_name' => $this->downFileInfo->downloadRealName ?? '',
  333. 'size' => $headers['size'] ?? 0,
  334. 'type' => $headers['type'] ?? 'image/jpeg',
  335. 'dir' => $this->downFileInfo->downloadFilePath ?? '',
  336. 'thumb_path' => $this->downFileInfo->downloadFilePath ?? '',
  337. 'time' => time(),
  338. ];
  339. } else {
  340. return [];
  341. }
  342. }
  343. /**
  344. * 文件上传
  345. * @return mixed
  346. */
  347. abstract public function move(string $file = 'file');
  348. /**
  349. * 文件流上传
  350. * @return mixed
  351. */
  352. abstract public function stream($fileContent, string $key = null);
  353. /**
  354. * 删除文件
  355. * @return mixed
  356. */
  357. abstract public function delete(string $filePath);
  358. /**
  359. * 实例化上传
  360. * @return mixed
  361. */
  362. abstract protected function app();
  363. /**
  364. * 拉取空间
  365. * @param string $region
  366. * @param bool $line
  367. * @param bool $shared
  368. * @return mixed
  369. */
  370. abstract public function listbuckets(string $region, bool $line = false, bool $shared = false);
  371. /**
  372. * 创建空间
  373. * @param string $name
  374. * @param string $region
  375. * @return mixed
  376. */
  377. abstract public function createBucket(string $name, string $region);
  378. /**
  379. * 获得区域
  380. * @return mixed
  381. */
  382. abstract public function getRegion();
  383. /**
  384. * 删除空间
  385. * @param string $name
  386. * @return mixed
  387. */
  388. abstract public function deleteBucket(string $name);
  389. /**
  390. * 绑定自定义域名
  391. * @param string $name
  392. * @param string $domain
  393. * @param string|null $region
  394. * @return mixed
  395. */
  396. abstract public function bindDomian(string $name, string $domain, string $region = null);
  397. /**
  398. * 设置跨域
  399. * @param string $name
  400. * @param string $region
  401. * @return mixed
  402. */
  403. abstract public function setBucketCors(string $name, string $region);
  404. /**
  405. * 获取上传密钥
  406. * @return mixed
  407. */
  408. abstract public function getTempKeys();
  409. /**
  410. * 获取缩略图
  411. * @return mixed
  412. */
  413. abstract public function thumb(string $filePath = '');
  414. /**
  415. * 添加水印
  416. * @return mixed
  417. */
  418. abstract public function water(string $filePath = '');
  419. }