1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
filehash.php
См. документацию.
1<?php
2namespace Bitrix\Clouds;
3
4use Bitrix\Main\Localization\Loc;
5use Bitrix\Main\ORM\Data\DataManager;
6use Bitrix\Main\ORM\Fields\DatetimeField;
7use Bitrix\Main\ORM\Fields\IntegerField;
8use Bitrix\Main\ORM\Fields\StringField;
9use Bitrix\Main\ORM\Fields\Validators\LengthValidator;
10use Bitrix\Main\ORM\Fields\ExpressionField;
11
12Loc::loadMessages(__FILE__);
13
39
41{
47 public static function getTableName()
48 {
49 return 'b_clouds_file_hash';
50 }
51
57 public static function getMap()
58 {
59 return [
60 new IntegerField(
61 'ID',
62 [
63 'primary' => true,
64 'autocomplete' => true,
65 'title' => Loc::getMessage('FILE_HASH_ENTITY_ID_FIELD'),
66 ]
67 ),
68 new IntegerField(
69 'BUCKET_ID',
70 [
71 'required' => true,
72 'title' => Loc::getMessage('FILE_HASH_ENTITY_BUCKET_ID_FIELD'),
73 ]
74 ),
75 new StringField(
76 'FILE_PATH',
77 [
78 'required' => true,
79 'validation' => [__CLASS__, 'validateFilePath'],
80 'title' => Loc::getMessage('FILE_HASH_ENTITY_FILE_PATH_FIELD'),
81 ]
82 ),
83 new IntegerField(
84 'FILE_SIZE',
85 [
86 'title' => Loc::getMessage('FILE_HASH_ENTITY_FILE_SIZE_FIELD'),
87 ]
88 ),
89 new DatetimeField(
90 'FILE_MTIME',
91 [
92 'title' => Loc::getMessage('FILE_HASH_ENTITY_FILE_MTIME_FIELD'),
93 ]
94 ),
95 new StringField(
96 'FILE_HASH',
97 [
98 'validation' => [__CLASS__, 'validateFileHash'],
99 'title' => Loc::getMessage('FILE_HASH_ENTITY_FILE_HASH_FIELD'),
100 ]
101 ),
102 ];
103 }
104
110 public static function validateFilePath()
111 {
112 return [
113 new LengthValidator(null, 760),
114 ];
115 }
116
122 public static function validateFileHash()
123 {
124 return [
125 new LengthValidator(null, 50),
126 ];
127 }
128
138 public static function addList($bucketId, array $files)
139 {
140 $bucketId = intval($bucketId);
142 $helper = $connection->getSqlHelper();
143 $values = [];
144 foreach ($files['file'] as $i => $file)
145 {
146 $fileSize = $files['file_size'][$i];
147 $fileMtime = \CCloudUtil::gmtTimeToDateTime($files['file_mtime'][$i]);
148 $fileHash = $files['file_hash'][$i];
149 $values [] = '('
150 . $bucketId
151 . ",'" . $helper->forSql($file) . "'"
152 . ',' . intval($fileSize)
153 . ",'" . $fileMtime->format('Y-m-d h:i:s') . "'"
154 . ",'" . $helper->forSql($fileHash) . "'"
155 . ')'
156 ;
157 }
158 $sql = '
159 INSERT INTO ' . static::getTableName() . '
160 (BUCKET_ID, FILE_PATH, FILE_SIZE, FILE_MTIME, FILE_HASH)
161 VALUES
162 ' . implode(",\n", $values) . '
163 ';
164 return $connection->query($sql);
165 }
166
178 public static function syncList($bucketId, $path, array $files, $prevLastKey)
179 {
180 $result = null;
181 $bucketId = intval($bucketId);
183 $helper = $connection->getSqlHelper();
184
185 $index = [];
186 foreach ($files['file'] as $i => $filePath)
187 {
188 $index[$path . $filePath] = $i;
189 }
190
191 $filter = [
192 '=BUCKET_ID' => $bucketId,
193 ];
194 if ($prevLastKey)
195 {
196 $filter['>FILE_PATH'] = $path . $prevLastKey;
197 }
198 if ($files['last_key'])
199 {
200 $filter['<=FILE_PATH'] = $path . $files['last_key'];
201 }
202 $fileList = static::getList([
203 'select' => ['ID', 'FILE_PATH', 'FILE_SIZE', 'FILE_HASH'],
204 'filter' => $filter,
205 ]);
206 while ($fileInfo = $fileList->fetch())
207 {
208 if (
209 array_key_exists($fileInfo['FILE_PATH'], $index)
210 && ($files['file_size'][$index[$fileInfo['FILE_PATH']]] == $fileInfo['FILE_SIZE'])
211 && ($files['file_hash'][$index[$fileInfo['FILE_PATH']]] == $fileInfo['FILE_HASH'])
212 )
213 {
214 unset($files['file'][$index[$fileInfo['FILE_PATH']]]);
215 }
216 else
217 {
218 $deleteResult = static::delete($fileInfo['ID']);
219 }
220 }
221
222 $values = [];
223 foreach ($files['file'] as $i => $file)
224 {
225 $fileSize = $files['file_size'][$i];
226 $fileMtime = \CCloudUtil::gmtTimeToDateTime($files['file_mtime'][$i]);
227 $fileHash = $files['file_hash'][$i];
228 $values [] = '('
229 . $bucketId
230 . ",'" . $helper->forSql($path . $file) . "'"
231 . ',' . intval($fileSize)
232 . ",'" . $fileMtime->format('Y-m-d h:i:s') . "'"
233 . ",'" . $helper->forSql($fileHash) . "'"
234 . ')'
235 ;
236 }
237
238 $insertSize = 1000;
239 while ($values)
240 {
241 $sql = '
242 INSERT INTO ' . static::getTableName() . '
243 (BUCKET_ID, FILE_PATH, FILE_SIZE, FILE_MTIME, FILE_HASH)
244 VALUES
245 ' . implode(",\n", array_splice($values, 0, $insertSize)) . '
246 ';
247 $result = $connection->query($sql);
248 }
249
250 return $result;
251 }
252
263 public static function syncEnd($bucketId, $path, $prevLastKey)
264 {
265 $bucketId = intval($bucketId);
267 $sqlHelper = $connection->getSqlHelper();
268 $delete = '
269 DELETE from ' . static::getTableName() . '
270 WHERE BUCKET_ID = ' . $bucketId . '
271 AND FILE_PATH like \'' . $sqlHelper->forSql($path) . '%\'
272 AND FILE_PATH > \'' . $sqlHelper->forSql($path . $prevLastKey) . '\'
273 ';
274 $result = $connection->query($delete);
275 return $result;
276 }
277
288 public static function addFile($bucketId, $path, array $fileInfo)
289 {
290 return static::add([
291 'BUCKET_ID' => $bucketId,
292 'FILE_PATH' => $path,
293 'FILE_SIZE' => $fileInfo['size'],
294 'FILE_MTIME' => \CCloudUtil::gmtTimeToDateTime($fileInfo['mtime']),
295 'FILE_HASH' => $fileInfo['hash'],
296 ]);
297 }
298
306 public static function getLastKey($bucketId)
307 {
308 $bucketId = intval($bucketId);
309 $connection = \Bitrix\Main\Application::getConnection();
310 $sql = 'SELECT max(FILE_PATH) LAST_KEY from ' . static::getTableName() . ' WHERE BUCKET_ID=' . $bucketId;
311 $last = $connection->query($sql)->fetch();
312 return $last && $last['LAST_KEY'] ? $last['LAST_KEY'] : '';
313 }
314
322 public static function deleteAll($bucketId)
323 {
324 $bucketId = intval($bucketId);
325 $connection = \Bitrix\Main\Application::getConnection();
326 $delete = 'DELETE from ' . static::getTableName() . ' WHERE BUCKET_ID=' . $bucketId;
327 $result = $connection->query($delete);
328 return $result;
329 }
330
339 public static function deleteByFilePath($bucketId, $filePath)
340 {
341 $bucketId = intval($bucketId);
342 $connection = \Bitrix\Main\Application::getConnection();
343 $sqlHelper = $connection->getSqlHelper();
344 $delete = '
345 DELETE from ' . static::getTableName() . '
346 WHERE BUCKET_ID = ' . $bucketId . "
347 AND FILE_PATH = '" . $sqlHelper->forSql($filePath) . "'
348 ";
349 $result = $connection->query($delete);
350 return $result;
351 }
352
363 public static function dirList($bucketId, $path, $order, $filter)
364 {
365 $connection = \Bitrix\Main\Application::getConnection();
366 $sqlHelper = $connection->getSqlHelper();
367
368 $query = \Bitrix\Clouds\FileHashTable::query();
369 $query->setSelect([
370 new ExpressionField(
371 'FILE_TYPE',
372 'case when position(\'/\' in substring(%s, length(\'' . $sqlHelper->forSql($path) . '\')+1)) > 0 then \'D\' else \'F\' end',
373 ['FILE_PATH']
374 ),
375 new ExpressionField(
376 'NAME',
377 'substring_index(substring(%s, length(\'' . $sqlHelper->forSql($path) . '\')+1), \'/\', 1)',
378 ['FILE_PATH']
379 ),
380 new ExpressionField(
381 'SUM_FILE_SIZE',
382 'SUM(%s)',
383 ['FILE_SIZE']
384 ),
385 new ExpressionField(
386 'MAX_FILE_MTIME',
387 'MAX(%s)',
388 ['FILE_MTIME']
389 ),
390 new ExpressionField(
391 'FILE_COUNT',
392 'COUNT(1)'
393 ),
394 ]);
395
396 $filter['=BUCKET_ID'] = $bucketId;
397 $filter['%=FILE_PATH'] = $path . '%';
398 $query->setFilter($filter);
399 $query->setGroup(['FILE_TYPE', 'NAME']);
400 $query->setOrder($order);
401
402 $sql = $query->getQuery();
403
404 return $connection->query($sql);
405 }
406
417 public static function duplicateList($bucketId, $filter, $order, $limit = 0)
418 {
420 $helper = $connection->getSqlHelper();
422 $query->registerRuntimeField('FILE_PATH', [
423 'expression' => [
424 $helper->getConcatFunction('%s', "'/'", '%s'), 'FILE.SUBDIR', 'FILE.FILE_NAME'
425 ]
426 ]);
427 $query->setSelect([
428 'FILE_HASH',
429 'FILE_SIZE',
430 new ExpressionField(
431 'FILE_COUNT',
432 'COUNT(distinct %s)',
433 ['FILE_PATH']
434 ),
435 new ExpressionField(
436 'FILE_ID_MIN',
437 'MIN(%s)',
438 ['FILE_ID']
439 ),
440 new ExpressionField(
441 'FILE_ID_MAX',
442 'MAX(%s)',
443 ['FILE_ID']
444 ),
445 ]);
446
447 $filter['=FILE.HANDLER_ID'] = $bucketId;
448 $filter['>FILE_COUNT'] = 1;
449 $query->setFilter($filter);
450 $query->setGroup(['FILE_HASH', 'FILE_SIZE']);
451 $query->setOrder($order);
452 if ($limit > 0)
453 {
454 $query->setLimit($limit);
455 }
456
457 $sql = $query->getQuery();
458
459 return $connection->query($sql);
460 }
461
471 public static function getFileDuplicates($bucketId, $fileHash, $fileSize)
472 {
474 'select' => [
475 'FILE_ID',
476 ],
477 'filter' => [
478 '=FILE.HANDLER_ID' => $bucketId,
479 '=FILE_HASH' => $fileHash,
480 '=FILE_SIZE' => $fileSize,
481 ],
482 'order' => [
483 'FILE_ID' => 'ASC',
484 ],
485 ]);
486
487 $result = [];
488 while ($fileDuplicate = $query->fetch())
489 {
490 $result[] = $fileDuplicate['FILE_ID'];
491 }
492 return $result;
493 }
494
501 public static function getDuplicatesStat($bucketId)
502 {
503 $bucketId = intval($bucketId);
505 $helper = $connection->getSqlHelper();
506 $sql = '
507 select sum(DUP_COUNT) DUP_COUNT, sum(DUP_SIZE) DUP_SIZE
508 from (
509 select
510 b_file_hash.FILE_SIZE
511 ,b_file_hash.FILE_HASH
512 ,count(distinct ' . $helper->getConcatFunction('b_file.SUBDIR', "'/'", 'b_file.FILE_NAME') . ')-1 DUP_COUNT
513 ,(count(distinct ' . $helper->getConcatFunction('b_file.SUBDIR', "'/'", 'b_file.FILE_NAME') . ")-1) * b_file_hash.FILE_SIZE DUP_SIZE
514 from
515 b_file_hash
516 inner join b_file on
517 b_file.ID = b_file_hash.FILE_ID
518 where
519 b_file.HANDLER_ID = '" . $bucketId . "'
520 group by
521 b_file_hash.FILE_SIZE, b_file_hash.FILE_HASH
522 having
523 count(distinct " . $helper->getConcatFunction('b_file.SUBDIR', "'/'", 'b_file.FILE_NAME') . ') > 1
524 ) t
525 ';
526
527 return $connection->query($sql)->fetch();
528 }
529
538 public static function copyToFileHash($lastKey, $pageSize)
539 {
540 global $DB;
542 $helper = $connection->getSqlHelper();
543
544 $lastKey = (int)$lastKey;
545 $pageSize = (int)$pageSize;
546 $sql = '
547 SELECT
548 b_file.ID as FILE_ID
549 ,b_clouds_file_hash.FILE_SIZE as FILE_SIZE
550 ,b_clouds_file_hash.FILE_HASH as FILE_HASH
551 FROM
552 b_file
553 INNER JOIN b_clouds_file_hash ON
554 b_clouds_file_hash.BUCKET_ID = ' . $DB->ToNumber('b_file.HANDLER_ID') . '
555 AND b_clouds_file_hash.FILE_PATH = ' . $helper->getConcatFunction("'/'", 'b_file.SUBDIR', "'/'", 'b_file.FILE_NAME') . '
556 LEFT JOIN b_file_duplicate ON
557 b_file_duplicate.DUPLICATE_ID = b_file.ID
558 WHERE
559 b_file.ID > ' . $lastKey . '
560 AND b_file_duplicate.DUPLICATE_ID is null
561 ORDER BY b_file.ID
562 LIMIT ' . $pageSize . '
563 ';
564
565 $fileIds = $connection->query('
566 SELECT
567 min(FILE_ID) as FILE_ID_MIN
568 ,max(FILE_ID) as FILE_ID_MAX
569 ,count(FILE_ID) FILE_ID_CNT
570 FROM (' . $sql . ') t
571 ')->fetch();
572
573 if ($fileIds['FILE_ID_CNT'] > 0)
574 {
575 $sql = $helper->getInsertIgnore(
576 'b_file_hash',
577 '(FILE_ID, FILE_SIZE, FILE_HASH)',
578 $sql
579 );
580
581 $connection->query($sql);
582 }
583
584 return $fileIds;
585 }
586
594 public static function prepareDuplicates($bucketId, &$fileIds)
595 {
596 $originalId = false;
597 if ($fileIds)
598 {
599 //Exclude any id that is already a duplicate
601 'select' => ['DUPLICATE_ID'],
602 'filter' => [
603 '=DUPLICATE_ID' => $fileIds,
604 ],
605 ]);
606 while ($duplicate = $duplicates->fetch())
607 {
608 //Others will be excluded from the process
609 $p = array_search($duplicate['DUPLICATE_ID'], $fileIds);
610 if ($p !== false)
611 {
612 unset($fileIds[$p]);
613 }
614 }
615 }
616
617 if ($fileIds)
618 {
619 //Search throught file id for any existing originals
621 'select' => ['ORIGINAL_ID'],
622 'filter' => [
623 '=ORIGINAL_ID' => $fileIds,
624 ],
625 'order' => ['ORIGINAL_ID' => 'ASC'],
626 ]);
627 while ($original = $originals->fetch())
628 {
629 //First will be used for future deduplication
630 if ($originalId === false)
631 {
632 $originalId = $original['ORIGINAL_ID'];
633 }
634
635 //Others will be excluded from the process
636 $p = array_search($original['ORIGINAL_ID'], $fileIds);
637 if ($p !== false)
638 {
639 unset($fileIds[$p]);
640 }
641 }
642 //None originals exists yet
643 if ($originalId === false)
644 {
645 $originalId = array_shift($fileIds);
646 }
647 }
648
649 return $originalId;
650 }
651}
$path
Определения access_edit.php:21
$connection
Определения actionsdefinitions.php:38
static duplicateList($bucketId, $filter, $order, $limit=0)
Определения filehash.php:417
static prepareDuplicates($bucketId, &$fileIds)
Определения filehash.php:594
static syncList($bucketId, $path, array $files, $prevLastKey)
Определения filehash.php:178
static getMap()
Определения filehash.php:57
static syncEnd($bucketId, $path, $prevLastKey)
Определения filehash.php:263
static copyToFileHash($lastKey, $pageSize)
Определения filehash.php:538
static getDuplicatesStat($bucketId)
Определения filehash.php:501
static getFileDuplicates($bucketId, $fileHash, $fileSize)
Определения filehash.php:471
static validateFilePath()
Определения filehash.php:110
static validateFileHash()
Определения filehash.php:122
static addList($bucketId, array $files)
Определения filehash.php:138
static getTableName()
Определения filehash.php:47
static getConnection($name="")
Определения application.php:638
static getList(array $parameters=array())
Определения datamanager.php:431
static gmtTimeToDateTime($str)
Определения util.php:46
background position
Определения file_new.php:745
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$result
Определения get_property_values.php:14
$query
Определения get_search.php:11
$p
Определения group_list_element_edit.php:23
$filter
Определения iblock_catalog_list.php:54
global $DB
Определения cron_frame.php:29
$pageSize
Определения csv_new_run.php:34
$files
Определения mysql_to_pgsql.php:30
$order
Определения payment.php:8
$i
Определения factura.php:643
font size
Определения invoice.php:442