FileService.class.php
8.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
<?php
/**
* Created by PhpStorm.
* User: liyifei2012it
* Date: 17/5/18
* Time: 11:36
*/
namespace Common\Service;
use Common\Common\Constant;
use Common\Model\FileModel;
class FileService extends AbstractService
{
// 构造方法
public function __construct()
{
parent::__construct();
$this->_d = new FileModel();
}
/**
* @desc 检查同级目录下文件、文件夹名称是否重复,重复则生成新文件、文件夹名称(引用)
* @author tangxingguo
* @param String $file_name 文件、文件夹名称
* @param Int $parent_id 父级目录ID
* @param Int $file_type 文件类型(1=文件夹;2=文件)
* @param Int $file_id 文件ID,编辑文件时传入
*/
public function checkFileName(&$file_name, $parent_id, $file_type, $file_id = 0)
{
// 同名文件出现的次数
static $count;
// 原始文件名
static $rawName;
// 同级目录下文件、文件夹列表
static $list;
// 同级目录下所有文件、文件夹名称
static $fileNames;
// 当前目录下所有文件夹或文件信息
if (empty($list)) {
$list = $this->list_by_conds(['parent_id' => $parent_id, 'file_type' => $file_type]);
$list = array_combine_by_key($list, 'file_id');
if ($file_id > 0) {
unset($list[$file_id]);
}
if (!empty($list)) {
$fileNames = array_column($list, 'file_name');
}
}
// 没有文件
if (empty($fileNames)) {
return;
}
// 赋值原始文件名
if (empty($rawName)) {
$rawName = $file_name;
}
// 存在重复文件,根据重复次数,拼接文件名
if (in_array($file_name, $fileNames)) {
$count++;
if ($file_type == Constant::FILE_TYPE_IS_DOC) {
// 文件
$suffix = end(explode('.', $rawName));
$name = mb_substr($rawName, 0, mb_strrpos($rawName, '.'));
$file_name = $name . '(' . $count . ').' . $suffix;
} else {
// 文件夹
$file_name = $rawName . '(' . $count . ')';
}
$this->checkFileName($file_name, $parent_id, $file_type);
}
}
/**
* @desc 取目录下所有子文件夹ID(包含自身)
* @author tangxingguo
* @param array $file_ids 目录ID
* @return array 子文件夹ID
*/
public function getChildIds($file_ids)
{
$folders = $this->formatDBData(['file_type' => Constant::FILE_TYPE_IS_FOLDER]);
// 取子文件夹ID(包含自身)
if (!empty($folders)) {
foreach ($file_ids as $value) {
if (isset($folders[$value])) {
$groupData = $this->dataGrouping($folders[$value]);
}
}
}
return isset($groupData) ? $groupData['file_id'] : [];
}
/**
* @desc 将多层级结构的数据根据字段分组返回
* @author tangxingguo
* @param array $arrTree 层级结构数组
* @return array 分组数据
* + array file_id 所有子类ID(包含自身)
* + array file_name 所有子类名称(包含自身)
*/
public function dataGrouping($arrTree)
{
static $data;
if (!is_array($arrTree)) {
return [];
}
foreach ($arrTree as $k => $v) {
if (is_array($v)) {
$this->dataGrouping($v);
} else {
$data[$k][] = $v;
}
}
return $data;
}
/**
* @desc 根据层级格式化数据库文件数据
* @author tangxingguo
* @param array $conds 数据库数据获取条件
* @return array
*/
public function formatDBData($conds = [])
{
$files = $this->list_by_conds($conds);
if (!empty($files)) {
$files = array_combine_by_key($files, 'file_id');
foreach ($files as $k => $v) {
$files[$v['parent_id']]['child'][] = &$files[$k];
}
} else {
$files = [];
}
return $files;
}
/**
* @desc 取当前文件所在目录层级
* @author tangxingguo
* @param int $file_id 文件ID
* @return int
*/
public function getLevel($file_id)
{
if ($file_id == 0) {
return 0;
}
$files = $this->formatDBData([]);
if (empty($files)) {
return 0;
}
$level = 1;
while ($files[$file_id]['parent_id'] > 0) {
$level++;
$file_id = $files[$file_id]['parent_id'];
}
return $level;
}
/**
* @desc 取当前目录所在路径
* @author tangxingguo
* @param int $file_id 目录ID
* @return array
*/
public function getPaths($file_id)
{
$dir = [];
$files = $this->formatDBData([]);
if (empty($files)) {
return $dir;
}
// 当前目录
$dir[] = [
'file_id' => $file_id,
'file_name' => $files[$file_id]['file_name'],
];
// 父级目录
while ($files[$file_id]['parent_id'] > 0) {
$file_id = $files[$file_id]['parent_id'];
$dir[] = [
'file_id' => $file_id,
'file_name' => $files[$file_id]['file_name'],
];
}
// 反序
return array_reverse($dir);
}
/**
* @desc 取目录所有文件个数以及目录大小
* @author tangxingguo
* @param $file_id
* @return array
*/
public function getFolderInfo($file_id)
{
$totalSize = 0;
$totalFile = 0;
$fileServ = new FileService();
$fileList = $fileServ->formatDBData([]);
if (!empty($fileList) && isset($fileList[$file_id])) {
$groupData = $fileServ->dataGrouping($fileList[$file_id]);
// 累加子文件尺寸
$totalSize = array_sum($groupData['at_size']);
// 文件个数
$totalFile = count($groupData['file_id']) -1;
}
return [$totalSize, $totalFile];
}
/**
* 获取子文件及子文件夹ID(含自身)
* @author liyifei
* @param array $file_ids 文件夹及文件ID
* @return array
*/
public function getFileByFileIds($file_ids)
{
// 区分文件夹和文件
list($folders, $files) = $this->diffFolderFile($file_ids);
if (empty($folders) && empty($files)) {
return [$folders, $files];
}
// 获取所有文件夹(顶级文件夹及子文件夹)
$folderIds = $this->getChildIds($folders);
if (!empty($folderIds)) {
// 获取所有文件夹下的文件
$fileList = $this->list_by_conds([
'parent_id' => $folderIds,
'file_type' => Constant::FILE_TYPE_IS_DOC,
]);
if (!empty($fileList)) {
$fileIds = array_column($fileList, 'file_id');
$files = array_merge($files, $fileIds);
}
}
return [$folderIds, $files];
}
/**
* 区分文件夹和文件
* @author liyifei
* @param array $file_ids 文件夹及文件ID
* @return array
*/
public function diffFolderFile($file_ids)
{
$folders = [];
$files = [];
$all_file = $this->formatDBData();
if (empty($file_ids) || empty($all_file)) {
return [$folders, $files];
}
foreach ($file_ids as $file_id) {
if (isset($all_file[$file_id])) {
switch ($all_file[$file_id]['file_type']) {
case Constant::FILE_TYPE_IS_FOLDER:
$folders[] = $file_id;
break;
case Constant::FILE_TYPE_IS_DOC:
$files[] = $file_id;
break;
}
}
}
return [$folders, $files];
}
}