Server IP : 80.87.202.40 / Your IP : 216.73.216.169 Web Server : Apache System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64 User : bitrix ( 600) PHP Version : 8.2.27 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : ON Directory : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/sender/lib/ |
Upload File : |
<?php /** * Bitrix Framework * @package bitrix * @subpackage sender * @copyright 2001-2012 Bitrix */ namespace Bitrix\Sender; use Bitrix\Main\DB; use Bitrix\Main\ORM; use Bitrix\Main\ORM\Fields\ExpressionField; use Bitrix\Main\ORM\Query\Query; use Bitrix\Main\Type as MainType; use Bitrix\Main\Localization\Loc; use Bitrix\Main\Loader; use Bitrix\Fileman\Block\Editor as BlockEditor; use Bitrix\Fileman\Block\EditorMail as BlockEditorMail; use Bitrix\Sender\Internals\Model\MessageFieldTable; use Bitrix\Sender\Internals\SqlBatch; use Bitrix\Sender\Internals\Model\FileInfoTable; Loc::loadMessages(__FILE__); class FileTable extends ORM\Data\DataManager { private static $fileList = []; public const TYPES = [ 'LETTER' => 0, 'TEMPLATE' => 1, ]; /** * Get table name * * @return string */ public static function getTableName() { return 'b_sender_file'; } /** * Return the map * * @return array */ public static function getMap() { return array( 'ID' => array( 'data_type' => 'integer', 'autocomplete' => true, 'primary' => true, ), 'FILE_ID' => array( 'data_type' => 'integer', 'required' => true, ), 'ENTITY_TYPE' => array( 'data_type' => 'integer', 'required' => true, ), 'ENTITY_ID' => array( 'data_type' => 'integer', 'required' => true, ), 'DATE_INSERT' => array( 'data_type' => 'datetime', 'required' => true, 'default_value' => new MainType\DateTime(), ), ); } public static function syncFiles(int $entityId, int $entityType, string $template, bool $deleteFiles = true, bool $onDeleteEntity = false) { preg_match_all( '@src="([^"]+)"@', $template, $matches ); $urls = array_pop($matches); // get file list from html $fileNameList = []; $fileNameSearchList = []; $files = []; foreach ($urls as $path) { preg_match("/[^\/|\\\]+$/", $path, $url); if (!$url) { continue; } if (!empty($url[0])) { $fileNameList[] = $url[0]; if (array_key_exists($url[0], static::$fileList)) { $files[] = static::$fileList[$url[0]]; continue; } $fileNameSearchList[] = $url[0]; } } $useSenderFileInfoTable = \COption::GetOptionString('sender', 'sender_file_info_load_completed', 'N') === 'Y'; $attachmentFileIds = []; $attachmentFiles = []; if ( $entityType === FileTable::TYPES['LETTER'] && $useSenderFileInfoTable ) { $attachmentFiles = self::getMessageAttachmentFiles($entityId); if (!empty($attachmentFiles)) { foreach ($attachmentFiles as $attachmentFile) { $attachmentFileIds[] = (int)$attachmentFile['ID']; } $files = array_merge($files, $attachmentFiles); } } if (!empty($fileNameSearchList)) { // get files from main FileTable which exists in html if ($useSenderFileInfoTable) { $selectedFiles = FileInfoTable::query() ->setSelect(['ID', 'FILE_NAME']) ->whereIn('FILE_NAME', $fileNameSearchList) ->setOrder(['ID' => 'ASC']) ->fetchAll() ; } else { $selectedFiles = \Bitrix\Main\FileTable::getList([ 'select' => ['ID', 'FILE_NAME'], 'filter' => [ '=MODULE_ID' => 'sender', '@FILE_NAME' => $fileNameSearchList, ], 'order' => [ 'ID' => 'ASC' ] ])->fetchAll(); } $files = array_merge($files, $selectedFiles); if (empty($selectedFiles)) { foreach ($fileNameList as $fileName) { static::$fileList[$fileName] = null; } } } $batchData = []; // get files in current sender file table $currentFiles = array_column(self::getCurrentFiles($entityId, $entityType), 'FILE_ID'); $preparedFiles = []; $alreadyAttachedFileIds = []; foreach ($currentFiles as $fileId) { if (in_array((int)$fileId, $attachmentFileIds, true)) { $alreadyAttachedFileIds[] = (int)$fileId; continue; } $preparedFiles[$fileId] = $fileId; } $filesToDelete = []; foreach ($files as $file) { if (is_null($file)) { continue; } if (!$onDeleteEntity && in_array((int)$file['ID'], $attachmentFileIds, true)) { continue; } if (!isset(static::$fileList[$file['FILE_NAME']])) { static::$fileList[$file['FILE_NAME']] = $file; } if ($onDeleteEntity && in_array($file['ID'], $preparedFiles)) { $filesToDelete[] = $file['ID']; unset($preparedFiles[$file['ID']]); continue; } // do nothing if file in current template if (in_array($file['ID'], $preparedFiles)) { unset($preparedFiles[$file['ID']]); continue; } if (isset($batchData[$file['FILE_NAME']])) { $filesToDelete[] = $file['ID']; continue; } foreach ($fileNameList as $fileName) { if ($fileName === $file['FILE_NAME']) { $batchData[$fileName] = [ 'ENTITY_TYPE' => $entityType, 'ENTITY_ID' => $entityId, 'FILE_ID' => $file['ID'], 'DATE_INSERT' => new MainType\DateTime() ]; } } } foreach ($attachmentFiles as $file) { if (in_array((int)$file['ID'], $alreadyAttachedFileIds, true)) { continue; } $batchData['ATTACHMENT_FILE' . $file['ID']] = [ 'ENTITY_TYPE' => $entityType, 'ENTITY_ID' => $entityId, 'FILE_ID' => $file['ID'], 'DATE_INSERT' => new MainType\DateTime() ]; } foreach ($preparedFiles as $file) { self::deleteIfCan($file, $entityId, $entityType, $deleteFiles); } foreach ($filesToDelete as $file) { self::deleteIfCan($file, $entityId, $entityType, $deleteFiles); } SqlBatch::insert(self::getTableName(), $batchData); } private static function getCurrentFiles(int $entityId, int $entityType) { return self::getList([ 'select' => ['FILE_ID'], 'filter' => [ '=ENTITY_ID' => $entityId, '=ENTITY_TYPE' => $entityType, ], ])->fetchAll(); } private static function getMessageAttachmentFiles(int $messageId, bool $useSenderFileInfoTable = true): array { $fileField = MessageFieldTable::getById([ 'MESSAGE_ID' => $messageId, 'CODE' => 'ATTACHMENT', ])->fetch(); if ( !$fileField || $fileField['TYPE'] !== 'file' || empty($fileField['VALUE']) ) { return []; } $attachmentFiles = explode(',', $fileField['VALUE']); $attachmentIds = []; foreach ($attachmentFiles as $attachmentFile) { if (is_numeric($attachmentFile)) { $attachmentIds[] = (int)$attachmentFile; } } if (empty($attachmentIds)) { return []; } if ($useSenderFileInfoTable) { $attachmentFiles = FileInfoTable::query() ->setSelect(['ID', 'FILE_NAME']) ->whereIn('ID', $attachmentIds) ->setOrder(['ID' => 'ASC']) ->fetchAll() ; } else { $attachmentFiles = \Bitrix\Main\FileTable::getList([ 'select' => ['ID', 'FILE_NAME'], 'filter' => [ '=MODULE_ID' => 'sender', '@ID' => $attachmentIds, ], 'order' => [ 'ID' => 'ASC' ], ])->fetchAll(); } return $attachmentFiles; } private static function deleteIfCan(int $fileId, int $entityId, int $entityType, bool $deleteFiles) { self::deleteList([ '=FILE_ID' => $fileId, '=ENTITY_TYPE' => $entityType, '=ENTITY_ID' => $entityId, ]); $hasFiles = self::getList([ 'select' => ['ID',], 'filter' => [ '=FILE_ID' => $fileId ], 'limit' => 1 ] )->fetch(); if ($deleteFiles) { $deleteFiles = 1 === \COption::GetOptionInt( 'sender', 'sender_file_load_completed', 0 ); } if (!$hasFiles && $deleteFiles) { \CFile::Delete($fileId); FileInfoTable::delete($fileId); } } /** * @param array $filter * @return \Bitrix\Main\DB\Result * @throws \Bitrix\Main\ArgumentException * @throws \Bitrix\Main\DB\SqlQueryException * @throws \Bitrix\Main\SystemException */ public static function deleteList(array $filter) { $entity = static::getEntity(); $connection = $entity->getConnection(); \CTimeZone::disable(); $sql = sprintf( 'DELETE FROM %s WHERE %s', $connection->getSqlHelper()->quote($entity->getDbTableName()), Query::buildFilterSql($entity, $filter) ); $res = $connection->query($sql); \CTimeZone::enable(); return $res; } }