403Webshell
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/mail/lib/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/mail/lib/mailmessageuid.php
<?php

namespace Bitrix\Mail;

use Bitrix\Mail\Helper\Message\MessageInternalDateHandler;
use Bitrix\Mail\Helper\MessageEventManager;
use Bitrix\Mail\Internals\MessageUploadQueueTable;
use Bitrix\Main\DB\Connection;
use Bitrix\Main\Entity;
use Bitrix\Main\EventManager;
use Bitrix\Main\Localization;
use Bitrix\Main\ORM\Fields\Relations\Reference;
use Bitrix\Main\ORM\Query\Join;

Localization\Loc::loadMessages(__FILE__);

/**
 * Class MailMessageUidTable
 *
 * DO NOT WRITE ANYTHING BELOW THIS
 *
 * <<< ORMENTITYANNOTATION
 * @method static EO_MailMessageUid_Query query()
 * @method static EO_MailMessageUid_Result getByPrimary($primary, array $parameters = array())
 * @method static EO_MailMessageUid_Result getById($id)
 * @method static EO_MailMessageUid_Result getList(array $parameters = array())
 * @method static EO_MailMessageUid_Entity getEntity()
 * @method static \Bitrix\Mail\EO_MailMessageUid createObject($setDefaultValues = true)
 * @method static \Bitrix\Mail\EO_MailMessageUid_Collection createCollection()
 * @method static \Bitrix\Mail\EO_MailMessageUid wakeUpObject($row)
 * @method static \Bitrix\Mail\EO_MailMessageUid_Collection wakeUpCollection($rows)
 */
class MailMessageUidTable extends Entity\DataManager
{
	public const OLD = 'Y';
	public const RECENT = 'N';
	public const DOWNLOADED = 'D';
	public const MOVING = 'M';
	public const REMOTE = 'R';
	public const LOST = 'L';

	public const EXCLUDED_COUNTER_STATUSES = [
		self::LOST,
		self::MOVING,
		self::REMOTE,
		self::OLD,
	];

	public static function getFilePath()
	{
		return __FILE__;
	}

	public static function getTableName()
	{
		return 'b_mail_message_uid';
	}

	/**
	 * @param array $filter
	 * @param array $fields
	 * @param  array $eventData - optional, for compatibility reasons, should have the following structure:
	 * [ ['HEADER_MD5' => .., 'MESSAGE_ID' => .., 'MAILBOX_USER_ID' => ..], [..]]
	 * @return \Bitrix\Main\DB\Result
	 * @throws \Bitrix\Main\ArgumentException
	 * @throws \Bitrix\Main\Db\SqlQueryException
	 * @throws \Bitrix\Main\ObjectException
	 * @throws \Bitrix\Main\ObjectPropertyException
	 * @throws \Bitrix\Main\SystemException
	 */
	public static function updateList(array $filter, array $fields, array $eventData = [], bool $sendEvent = true)
	{
		$entity = static::getEntity();
		$connection = $entity->getConnection();

		$result = $connection->query(sprintf(
			"UPDATE %s SET %s WHERE %s",
			$connection->getSqlHelper()->quote($entity->getDbTableName()),
			$connection->getSqlHelper()->prepareUpdate($entity->getDbTableName(), $fields)[0],
			Entity\Query::buildFilterSql($entity, $filter)
		));
		$eventManager = EventManager::getInstance();
		$eventKey = $eventManager->addEventHandler(
			'mail',
			'onMailMessageModified',
			array(MessageEventManager::class, 'onMailMessageModified')
		);

		if ($sendEvent)
		{
			$event = new \Bitrix\Main\Event('mail', 'onMailMessageModified', array(
				'MAIL_FIELDS_DATA' => $eventData,
				'UPDATED_FIELDS_VALUES' => $fields,
				'UPDATED_BY_FILTER' => $filter,
			));
			$event->send();
			EventManager::getInstance()->removeEventHandler('mail', 'onMailMessageModified', $eventKey);
		}

		return $result;
	}

	/**
	 * @param array $filter
	 * @param array $messages
	 * @param int|false $limit
	 * @return bool
	 * @throws \Bitrix\Main\ArgumentException
	 * @throws \Bitrix\Main\Db\SqlQueryException
	 * @throws \Bitrix\Main\ObjectPropertyException
	 * @throws \Bitrix\Main\SystemException
	 */
	public static function deleteList(array $filter, array $messages = [], $limit = false, bool $sendEvent = true): bool
	{
		$eventName = MessageEventManager::EVENT_DELETE_MESSAGES;

		$messages = static::selectMessagesToBeDeleted(
			MessageEventManager::getRequiredFieldNamesForEvent($eventName),
			$filter,
			$messages,
			$limit
		);

		if (empty($messages))
		{
			return false;
		}

		$entity = static::getEntity();
		$connection = $entity->getConnection();

		$portionLimit = 200;

		$messagesCount = count($messages);

		for ($i = 0; $i < $messagesCount; $i=$i+$portionLimit)
		{
			$portion = array_slice($messages, $i, $portionLimit);

			$query = sprintf(
				' FROM %s WHERE ID IN (\'' . join("','", array_column($portion, 'ID')) . '\')',
				$connection->getSqlHelper()->quote($entity->getDbTableName()),
			);

			self::insertIntoDeleteMessagesQueue($connection, $query);

			$connection->query(sprintf('DELETE %s', $query));
		}

		$remains=[];

		if($limit === false)
		{
			$remains = array_column(
				static::selectMessagesToBeDeleted(
					MessageEventManager::getRequiredFieldNamesForEvent($eventName),
					$filter,
					$messages
				),
				'MESSAGE_ID'
			);
		}
		else
		{
			if ($messagesIds = array_column($messages, 'MESSAGE_ID') )
			{
				$remains = array_column(
					static::getList(
						[
							'select' => [
								'MESSAGE_ID',
							],
							'filter' => [
								'@MESSAGE_ID' => $messagesIds,
							],
						]
					)->fetchAll(),
					'MESSAGE_ID'
				);
			}
		}

		if ($sendEvent)
		{
			//Checking that the values were actually deleted:
			$deletedMessages = array_filter(
				$messages,
				function ($item) use ($remains) {
					return !in_array($item['MESSAGE_ID'], $remains);
				}
			);

			$eventManager = EventManager::getInstance();
			$eventKey = $eventManager->addEventHandler(
				'mail',
				'onMailMessageDeleted',
				array(MessageEventManager::class, 'onMailMessageDeleted')
			);
			$event = new \Bitrix\Main\Event('mail', 'onMailMessageDeleted', array(
				'MAIL_FIELDS_DATA' => $deletedMessages,
				'DELETED_BY_FILTER' => $filter,
			));
			$event->send();
			EventManager::getInstance()->removeEventHandler('mail', 'onMailMessageDeleted', $eventKey);
		}

		return true;
	}

	public static function getLocalUID(int $mailboxId, string $dirPath, string $dirUIDv, string $order): int
	{
		$additionalFilter = [];

		if (\Bitrix\Mail\Helper\LicenseManager::getSyncOldLimit() > 0)
		{
			$additionalFilter = [
				'>INTERNALDATE' => \Bitrix\Main\Type\Date::createFromTimestamp(strtotime(sprintf('-%u days', \Bitrix\Mail\Helper\LicenseManager::getSyncOldLimit()))),
			];
		}

		$row = self::getRow(
			[
				'select' => [
					'MSG_UID'
				],
				'filter' => array_merge([
					'=MAILBOX_ID' => $mailboxId,
					'=DIR_MD5' => md5($dirPath),
					'=DIR_UIDV' => $dirUIDv,
					'>MSG_UID' => 0,
					'=IS_OLD' => 'N',
					'!=MESSAGE_ID' => 0,
					'==DELETE_TIME' => 0,
				], $additionalFilter),
				'order' => [
					'MSG_UID' => $order,
				],
			]
		);

		if (!isset($row['MSG_UID']))
		{
			return 0;
		}

		return (int)$row['MSG_UID'];
	}

	public static function getLastLocalUID(int $mailboxId, string $dirPath, string $dirUIDv): int
	{
		return self::getLocalUID($mailboxId, $dirPath, $dirUIDv, 'DESC');
	}

	public static function getFirstLocalUID(int $mailboxId, string $dirPath, string $dirUIDv): int
	{
		return self::getLocalUID($mailboxId, $dirPath, $dirUIDv, 'ASC');
	}

	public static function getMessage(
		int $mailboxId,
		$select,
		int $id = null,
		int $uid = null,
	): array|null
	{
		if (!is_null($id))
		{
			$filter = [
				'=MESSAGE_ID' => $id,
				'=MAILBOX_ID' => $mailboxId,
			];
		}
		else if(!is_null($uid))
		{
			$filter = [
				'=MSG_UID' => $uid,
				'=MAILBOX_ID' => $mailboxId,
			];
		}
		else
		{
			return null;
		}

		return self::getRow(
			[
				'select' => $select,
				'filter' => $filter,
			]
		);
	}

	/**
	 * Insert into delete queue table
	 *
	 * @param Connection $connection DB Connection
	 * @param string $query Query from and where
	 *
	 * @return void
	 * @throws \Bitrix\Main\DB\SqlQueryException
	 */
	private static function insertIntoDeleteMessagesQueue(Connection $connection, string $query): void
	{
		$sqlHelper = $connection->getSqlHelper();
		$messageDeleteTableName = $sqlHelper->quote(Internals\MessageDeleteQueueTable::getTableName());
		$insertFields = ' (ID, MAILBOX_ID, MESSAGE_ID) ';
		$fromSelect = sprintf('(SELECT ID, MAILBOX_ID, MESSAGE_ID %s)', $query);
		$insertQuery = $sqlHelper->getInsertIgnore($messageDeleteTableName, $insertFields, $fromSelect);
		$connection->query($insertQuery);
	}

	public static function getPresetRemoveFilters()
	{
		return [
			'==DELETE_TIME' => 0,
		];
	}

	/**
	 * @param array $filter
	 * @return \Bitrix\Main\DB\Result
	 * @throws \Bitrix\Main\ArgumentException
	 * @throws \Bitrix\Main\Db\SqlQueryException
	 * @throws \Bitrix\Main\SystemException
	 */
	public static function deleteListSoft(array $filter)
	{
		$entity = static::getEntity();
		$connection = $entity->getConnection();
		$filter = array_merge($filter , static::getPresetRemoveFilters());

		//mark selected messages for deletion if there are no messages in the download queue
		$query = sprintf(
			'UPDATE %s SET %s WHERE %s AND NOT EXISTS (SELECT 1 FROM %s WHERE %s)',
			$connection->getSqlHelper()->quote($entity->getDbTableName()),
			$connection->getSqlHelper()->prepareUpdate($entity->getDbTableName(), [
				'DELETE_TIME' => time(),
			])[0],
			Entity\Query::buildFilterSql(
				$entity,
				$filter
			),
			$connection->getSqlHelper()->quote(Internals\MessageUploadQueueTable::getTableName()),
			Entity\Query::buildFilterSql(
				$entity,
				[
					'=ID' => new \Bitrix\Main\DB\SqlExpression('?#', 'ID'),
					'=MAILBOX_ID' => new \Bitrix\Main\DB\SqlExpression('?#', 'MAILBOX_ID'),
				]
			)
		);

		$result = $connection->query($query);
		$count = $connection->getAffectedRowsCount();
		$result->setCount($count > 0 ? $count : 0);

		return $result;
	}

	/**@
	 * @param $fields
	 * @param $filter
	 * @param array $eventData
	 * @param int|false $limit
	 * @return array
	 * @throws \Bitrix\Main\ArgumentException
	 * @throws \Bitrix\Main\ObjectPropertyException
	 * @throws \Bitrix\Main\SystemException
	 */
	private static function selectMessagesToBeDeleted($fields, $filter, array $eventData, $limit = false): array
	{
		$result = array();

		$primary = array('ID', 'MAILBOX_ID');

		$eventData = array_values($eventData);

		if (empty($eventData))
		{
			$select = $fields;
		}
		else
		{
			$select = array_diff($fields, array_intersect($fields, ...array_map('array_keys', $eventData)));

			if (empty($select))
			{
				return $eventData;
			}

			if (array_diff($primary, array_intersect($primary, ...array_map('array_keys', $eventData))))
			{
				$select = $fields;
			}
			else
			{
				foreach ($eventData as $item)
				{
					$key = sprintf('%u:%s', $item['MAILBOX_ID'], $item['ID']);
					$result[$key] = $item;
				}
			}
		}

		$select = array_unique(array_merge($primary, $select));

		$mailsFilter = $filter;
		$mailsFilter['==IS_IN_QUEUE'] = false;
		$queueSubquery = MessageUploadQueueTable::query();
		$queueSubquery->addFilter('=ID', new \Bitrix\Main\DB\SqlExpression('%s'));
		$queueSubquery->addFilter('=MAILBOX_ID', new \Bitrix\Main\DB\SqlExpression('%s'));
		$emailsForDeleteQuery = MailMessageUidTable::query()
			->registerRuntimeField(new Entity\ExpressionField(
				'IS_IN_QUEUE',
				sprintf('EXISTS(%s)', $queueSubquery->getQuery()),
				['ID', 'MAILBOX_ID']
			))
			->setFilter($mailsFilter);

		if($limit !== false)
		{
			$emailsForDeleteQuery->setLimit($limit);
		}

		foreach ($select as $index => $selectingField)
		{
			if (strncmp('MAILBOX_', $selectingField, 8) === 0 && !MailMessageUidTable::getEntity()->hasField($selectingField))
			{
				$emailsForDeleteQuery->addSelect('MAILBOX.'.mb_substr($selectingField, 8), $selectingField);
				continue;
			}
			$emailsForDeleteQuery->addSelect($selectingField);
		}

		$res = $emailsForDeleteQuery->exec();
		while ($item = $res->fetch())
		{
			$key = sprintf('%u:%s', $item['MAILBOX_ID'], $item['ID']);
			$result[$key] = array_merge((array) $result[$key], $item);
		}

		return array_values($result);
	}

	/**
	 * Merge data. Insert-update.
	 *
	 * @param array $insert Insert fields.
	 * @param array $update Update fields.
	 * @return void
	 * @throws \Bitrix\Main\ArgumentException
	 * @throws \Bitrix\Main\Db\SqlQueryException
	 * @throws \Bitrix\Main\SystemException
	 */
	public static function mergeData(array $insert, array $update)
	{
		$entity = static::getEntity();
		$connection = $entity->getConnection();
		$helper = $connection->getSqlHelper();

		$sql = $helper->prepareMerge($entity->getDBTableName(), $entity->getPrimaryArray(), $insert, $update);

		$sql = current($sql);
		if($sql <> '')
		{
			$connection->queryExecute($sql);
			$entity->cleanCache();
		}
	}

	public static function getMap()
	{
		return array(
			'ID' => array(
				'data_type' => 'string',
				'primary'   => true,
			),
			'MAILBOX_ID' => array(
				'data_type' => 'integer',
				'primary'   => true,
			),
			'DIR_MD5' => array(
				'data_type' => 'string',
			),
			'DIR_UIDV' => array(
				'data_type' => 'integer',
			),
			'MSG_UID' => array(
				'data_type' => 'integer',
			),
			'INTERNALDATE' => array(
				'data_type' => 'datetime',
			),
			'HEADER_MD5' => array(
				'data_type' => 'string',
			),
			'IS_SEEN' => array(
				'data_type' => 'enum',
				'values'    => array('Y', 'N', 'S', 'U'),
			),
			'IS_OLD' => array(
				'data_type' => 'enum',
				'values'    => [
					self::OLD,
					self::RECENT,
					self::DOWNLOADED,
					self::MOVING,
					self::REMOTE,
					self::LOST,
				],
			),
			'SESSION_ID' => array(
				'data_type' => 'string',
				'required'  => true,
			),
			'TIMESTAMP_X' => array(
				'data_type' => 'datetime',
			),
			'DATE_INSERT' => array(
				'data_type' => 'datetime',
				'required'  => true,
			),
			'MESSAGE_ID' => array(
				'data_type' => 'integer',
				'required'  => true,
			),
			'MAILBOX' => array(
				'data_type' => 'Bitrix\Mail\Mailbox',
				'reference' => array('=this.MAILBOX_ID' => 'ref.ID'),
			),
			'MESSAGE' => array(
				'data_type' => 'Bitrix\Mail\MailMessage',
				'reference' => array('=this.MESSAGE_ID' => 'ref.ID'),
			),
			'DELETE_TIME' => array(
				'data_type' => 'integer',
				'default' => 0,
			),
			new Reference(
				'MESSAGE_TABLE',
				MailMessageTable::class,
				Join::on('this.MESSAGE_ID', 'ref.ID')
					->whereColumn('this.MAILBOX_ID', 'ref.MAILBOX_ID')
			),
		);
	}
	/**
	 * @param Entity\Event $event
	 * @return Entity\EventResult
	 */
	public static function onAfterUpdate(Entity\Event $event)
	{
		$result = new Entity\EventResult;
		$parameters = $event->getParameters();
		if ($parameters['primary'] && is_set($parameters['fields']['IS_OLD']))
		{
			$message = self::getByPrimary($parameters['primary'], [
				'select' => [
					'MAILBOX_ID',
					'DIR_MD5',
					'INTERNALDATE'
				],
			])->fetch();

			if (!$message)
			{
				return $result;
			}

			$internalDate = $message['INTERNALDATE'];
			$mailboxId = (int)$message['MAILBOX_ID'];
			$dirMd5 = $message['DIR_MD5'];

			$startInternalDate = MessageInternalDateHandler::getStartInternalDateForDir($mailboxId, dirMd5: $dirMd5);

			if (!is_null($startInternalDate) && $internalDate <= $startInternalDate)
			{
				$updateResult = MessageInternalDateHandler::clearStartInternalDate($mailboxId, $dirMd5);
				if (!$updateResult->isSuccess())
				{
					$result->setErrors($updateResult->getErrors());
				}
			}
		}

		return $result;
	}

}

Youez - 2016 - github.com/yon3zu
LinuXploit