ImageManager.php 9.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. <?php namespace App\Http\Controllers\Admin;
  2. use Illuminate\Pagination\LengthAwarePaginator;
  3. /**
  4. * 图片管理
  5. *
  6. */
  7. class ImageManager extends Auth{
  8. //图片保存路径
  9. private $upload_url;
  10. /* 初始化 */
  11. protected function init($uid){
  12. // 上传路径
  13. $this->upload_url = DIR_IMAGE.'images/'.$uid;
  14. // 如果路径不存在,创建
  15. if ( !is_dir($this->upload_url) ) mkdir($this->upload_url, 0755,TRUE);
  16. }
  17. //图片和文件夹展示
  18. public function index(){
  19. // 初始化
  20. $this->init(admin('uid'));
  21. // 获取参数
  22. $data = request()->all();
  23. // 目录
  24. $directory = isset($data['directory']) ? $data['directory'] : '';
  25. //新建文件夹
  26. $data['folder_url'] = url('admin/image_manager/folder?'.http_build_query(['directory'=>$directory]));
  27. //图片上传
  28. $data['upload_url'] = url('admin/image_manager/upload?'.http_build_query(['directory'=>$directory]));
  29. //删除
  30. $data['delete_url'] = url('admin/image_manager/delete?');
  31. //搜索
  32. $data['search_url'] = url('admin/image_manager/index?'.http_build_query(['directory'=>$directory]));
  33. // 获取数据
  34. $file_data = $this->get_file_data($data);
  35. //dd($file_data);
  36. // 图片数据
  37. $data['images'] = $file_data['images'];
  38. $data['pagination'] = $file_data['pagination'];
  39. $data['parent'] = $this->get_parent_url($data);
  40. $data['refresh'] =$this->get_refresh_url($data);
  41. $this->assign('data',$data);
  42. $this->assign('heading_title','图片管理器');
  43. return $this->fetch();
  44. }
  45. public function get_dir($d){
  46. $dir='';
  47. foreach ($d as $v) {
  48. $dir.=$v.'/';
  49. }
  50. $dir = substr($dir,0,strlen($dir)-1);
  51. return $dir;
  52. }
  53. //图片上传
  54. public function upload(){
  55. // 初始化
  56. $this->init(admin('uid'));
  57. // 接收参数
  58. $directory = request('directory','');
  59. // 验证是否有这个文件夹
  60. $directory = $directory ? $this->upload_url.'/'.str_replace('-','/', $directory) : $this->upload_url;
  61. // Check its a directory
  62. if( !is_dir($directory) ) return ['error'=>'不是一个文件夹'];
  63. // 接收文件
  64. $files = request()->file('file');
  65. // 循环上传的文件
  66. foreach( $files as $file ) {
  67. // 仅支持字母数字-_
  68. if( !preg_match('/^[A-Za-z0-9\-\_\.]+$/',$file->getClientOriginalName() )) return ['error'=>'仅支持字母数字-_组合'];
  69. //保存图片
  70. $info = $file->move($directory,$file->getClientOriginalName());
  71. // 如果有错误
  72. if( !$info ) return ['error'=>$file->getError()];
  73. }
  74. // 上传成功
  75. return ['success'=>'上传成功'];
  76. }
  77. /**
  78. * 新建文件夹
  79. *
  80. */
  81. public function folder(){
  82. // 初始化
  83. $this->init(admin('uid'));
  84. // 接收参数
  85. $directory = request('directory','');
  86. // 要创建的目录名
  87. $folder = request('folder','');
  88. // 错误提示
  89. if( !$folder ) return ['error'=>'目录名必填'];
  90. // 避免特殊字符
  91. $folder = html_entity_decode($folder, ENT_QUOTES, 'UTF-8');
  92. // 仅支持字母数字-_
  93. if( !preg_match('/^[A-Za-z0-9\_\.]+$/',$folder) ) return ['error'=>$folder.' 文件夹仅支持字母数字_组合'];
  94. // 验证是否有这个文件夹
  95. $directory = $directory ? $this->upload_url.'/'.str_replace('-','/', $directory) : $this->upload_url.'/';
  96. // 替换上级目录
  97. $folder = str_replace(['../', '..\\', '..'],'',$folder,$count);
  98. // 有上级目录
  99. if( $count ) return ['error'=>'不支持创建上级目录'];
  100. // 不允许多级
  101. if( count(explode('/',$folder)) > 1 ) return ['error'=>'不支持直接创建多级目录'];
  102. // 替换上一级
  103. $folder = '/' . trim($folder,'/').'/';
  104. // 拼接路径
  105. $folder = $directory . $folder;
  106. // 如果路径不存在,创建
  107. if ( is_dir($folder) ) return ['error'=>'目录已存在'];
  108. // 创建文件夹
  109. mkdir($folder, 0755, TRUE);
  110. // 创建成功
  111. return ['success'=>'创建成功'];
  112. }
  113. //删除图片和文件夹
  114. public function delete(){
  115. // 初始化
  116. $this->init(admin('uid'));
  117. // 接收参数
  118. $paths = request('path',[]);
  119. // 没有要删除的文件夹
  120. if( !$paths ) return ['success'=>'非法操作'];
  121. // 删除
  122. foreach ($paths as $key => $value) {
  123. // 替换路径
  124. $value = str_replace('-','/', $value);
  125. // 判断是否增加路径
  126. $paths[$key] = is_dir($value) ? $value : DIR_IMAGE.$value;
  127. }
  128. // 调用删除
  129. $this->deleteFolderAndFile($paths);
  130. // 清除缓存
  131. $this->deleteFolderAndFile([DIR_IMAGE.'cache/images/']);
  132. // 删除成功
  133. return ['success'=>'删除成功'];
  134. }
  135. /**
  136. * 删除文件夹以及文件
  137. *
  138. * @param $paths 路径
  139. *
  140. */
  141. private function deleteFolderAndFile($paths){
  142. // 循环处理
  143. foreach ($paths as $value) {
  144. // 替换掉前后路径
  145. $value = str_replace(['../', '..\\', '..'],'', $value);
  146. // 替换成斜杠路径
  147. $value = str_replace('-','/', $value);
  148. // 拼接路径
  149. $value = $value;
  150. // 判断是文件么
  151. if( is_file($value) ){
  152. // 文件直接删除
  153. unlink($value);
  154. }else{
  155. // 如果是目录
  156. $files = [];
  157. // Make path into an array
  158. $path = [$value];
  159. // While the path array is still populated keep looping through
  160. while (count($path) != 0) {
  161. $next = array_shift($path);
  162. foreach ( glob($next) as $file) {
  163. // If directory add to path array
  164. if ( is_dir($file) ) $path[] = $file . '/*';
  165. // Add the file to the files to be deleted array
  166. $files[] = $file;
  167. }
  168. }
  169. // Reverse sort the file array
  170. rsort($files);
  171. foreach ($files as $file) {
  172. // If file just delete
  173. if (is_file($file)) {
  174. @unlink($file);
  175. // If directory use the remove directory function
  176. } elseif (is_dir($file)) {
  177. @rmdir($file);
  178. }
  179. }
  180. }
  181. }
  182. // 返回结果
  183. return ['success'=>'删除成功'];
  184. }
  185. //取得上一级的链接
  186. public function get_parent_url($data){
  187. $url = [];
  188. if (isset($data['directory'])) {
  189. // 验证是否有这个文件夹
  190. $d = explode('-', $data['directory'] );
  191. $dir = '';
  192. if(count($d)>1){
  193. for ($i=0; $i <(count($d)-1); $i++) {
  194. if($i<(count($d)-2)){
  195. $dir.=$d[$i].'-';
  196. }else{
  197. $dir.=$d[$i];
  198. }
  199. }
  200. $url['directory']=$dir;
  201. }
  202. }
  203. if (isset($data['target'])) {
  204. $url['target']=$data['target'];
  205. }
  206. if (isset($data['thumb'])) {
  207. $url['thumb'] =$data['thumb'];
  208. }
  209. return url('admin/image_manager/index?'.http_build_query($url));
  210. }
  211. //取得刷新的链接(重新加载当前页面的数据)
  212. public function get_refresh_url($data){
  213. $url = [];
  214. if (isset($data['directory'])) {
  215. $url['directory']=$data['directory'];
  216. }
  217. if (isset($data['target'])) {
  218. $url['target']=$data['target'];
  219. }
  220. if (isset($data['thumb'])) {
  221. $url['thumb'] =$data['thumb'];
  222. }
  223. return url('admin/image_manager/index?'.http_build_query($url));
  224. }
  225. //取得图片文件,文件夹数据,分页数据
  226. public function get_file_data($data){
  227. // 判断是不是有搜索名称
  228. $filter_name = isset($data['filter_name']) ? rtrim(str_replace(['../', '..\\', '..', '*'], '', $data['filter_name']), '/') : null;
  229. // 验证是否有这个文件夹
  230. $directory = empty( $data['directory'] ) ? $this->upload_url : $this->upload_url.'/'.str_replace('-','/', $data['directory']);
  231. // 取得文件夹
  232. $directories = (array) glob($directory . '/' . $filter_name . '*', GLOB_ONLYDIR);
  233. // 取得文件
  234. $files = (array) glob($directory . '/' . $filter_name . '*.{jpg,jpeg,png,gif,JPG,JPEG,PNG,GIF}', GLOB_BRACE);
  235. // 合并文件夹和文件
  236. $images = array_merge($directories, $files);
  237. // 如果没有文件或文件夹
  238. if( empty($images) ) return ['images'=>null,'pagination'=>null];
  239. if( isset($images['error']) ) return ['images'=>null,'pagination'=>null,'error'=>$images['error']];
  240. // 如果没有文件或文件夹
  241. if( !$images ) return ['images'=>null,'pagination'=>null];
  242. //分页用链接
  243. $url = [];
  244. if ( isset($data['directory']) ) $url['directory'] = $data['directory'];
  245. if ( isset($data['filter_name']) ) $url['filter_name'] = html_entity_decode($data['filter_name'], ENT_QUOTES, 'UTF-8');
  246. if ( isset($data['target']) ) $url['target'] = $data['target'];
  247. if ( isset($data['thumb']) ) $url['thumb'] = $data['thumb'];
  248. // 分页
  249. $pagination = new LengthAwarePaginator( array_slice($images,(16*(request('page')?request('page')-1:0)),16) ,count($images),16,null,['path'=>url('admin/image_manager/index?'.http_build_query($url))]);
  250. // 图片
  251. $images = $pagination->items();
  252. // 循环所有目录及文件
  253. foreach ($images as $image) {
  254. // 获取文件名
  255. $name = basename($image);
  256. // 获取后缀
  257. $ext = pathinfo($image,PATHINFO_EXTENSION);
  258. // 临时数据
  259. $temp = [];
  260. $thumb = mb_substr($image, mb_strlen(DIR_IMAGE),mb_strlen($image));
  261. //echo ($thumb);
  262. // 如果是图片显示
  263. if( in_array($ext,['jpg','jpeg','png','gif','JPG','JPEG','PNG','GIF']) ){
  264. // 组合参数
  265. //$temp['thumb'] = path_compat($thumb, 100, 100);
  266. $temp['thumb'] = $thumb;
  267. $temp['name'] = $name;
  268. $temp['type'] = 'image';
  269. $temp['path'] = $thumb;
  270. // 赋值
  271. $result['images'][] = $temp;
  272. }
  273. // 如果没有后缀,是目录
  274. if( !$ext ){
  275. // url跳转时的目录
  276. $url['directory'] = rtrim(str_ireplace('/', '-', mb_substr($image, mb_strlen($this->upload_url.'/'),mb_strlen($image))),'-');
  277. // 显示时的目录
  278. $path = str_ireplace('/', '-', $image);
  279. // 打开
  280. if ( isset($data['target']) ) $url['target'] = $data['target'];
  281. // 缩略
  282. if (isset($data['thumb'])) $url['thumb'] = $data['thumb'];
  283. // 组合参数
  284. $temp['thumb'] = '';
  285. $temp['name'] = $name;
  286. $temp['type'] = 'directory';
  287. $temp['path'] = $path;
  288. $temp['href'] = url('admin/image_manager/index?'.http_build_query($url));
  289. // 赋值
  290. $result['images'][] = $temp;
  291. }
  292. }
  293. //分页显示
  294. $result['pagination'] = $pagination->render();
  295. //返回列表数据
  296. return $result;
  297. }
  298. }