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/ilovecveti.ru/bitrix/modules/calendar/lib/sync/managers/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/ilovecveti.ru/bitrix/modules/calendar/lib/sync/managers/eventqueuemanager.php
<?php

namespace Bitrix\Calendar\Sync\Managers;

use Bitrix\Calendar\Core;
use Bitrix\Calendar\Core\Base\Date;
use Bitrix\Calendar\Sync\Builders\BuilderConnectionFromArray;
use Bitrix\Calendar\Sync\Connection\Connection;
use Bitrix\Calendar\Sync\Connection\EventConnection;
use Bitrix\Calendar\Sync\Dictionary;
use Bitrix\Calendar\Sync\Factories\FactoryBuilder;
use Bitrix\Calendar\Sync\Util\Context;
use Bitrix\Calendar\Sync\Util\EventContext;
use Bitrix\Main\ArgumentException;
use Bitrix\Main\DI\ServiceLocator;
use Bitrix\Main\Loader;
use Bitrix\Main\ObjectException;
use Bitrix\Main\ObjectNotFoundException;
use Bitrix\Main\ObjectPropertyException;
use Bitrix\Main\SystemException;
use Bitrix\Main\Type;
use Exception;

class EventQueueManager
{
	public const CHECK_EVENTS_PERIOD = 300; // length in seconds
	private const CHECK_ENTRY_LIMIT = 10;
	private const SHIFT_DATE_RETRY_COUNT = 25;
	private const MAX_RETRY_COUNT = 20;
	private array $connectionList = [];

	/**
	 * @var Core\Mappers\Factory
	 */
	private Core\Mappers\Factory $mapperFactory;

	/**
	 * @throws ObjectNotFoundException
	 */
	public function __construct()
	{
		$this->mapperFactory = ServiceLocator::getInstance()->get('calendar.service.mappers.factory');
	}

	/**
	 * @return string|null
	 * @throws ArgumentException
	 * @throws ObjectNotFoundException
	 * @throws ObjectPropertyException
	 * @throws SystemException|\Bitrix\Main\LoaderException
	 */
	public static function checkEvents(): ?string
	{
		if (
			!Loader::includeModule('calendar')
			|| !Loader::includeModule('dav')
		)
		{
			return null;
		}

		$qm = self::createInstance();

		$entriesDb = $qm::getEventListDb();
		while ($queueItem = $entriesDb->Fetch())
		{
			$connection = $qm->getConnectionForQueueItem($queueItem);

			$event = $qm->mapperFactory->getEvent()->getEntity((int)$queueItem['EVENT_ID']);
			if (!$event)
			{
				continue;
			}

			$context = $qm->prepareEventContext(
				[
					'connection' => $connection,
					'event' => $event,
					'queueItem' => $queueItem,
				]
			);

			if ($event->getOwner() === null || $event->getOwner()->getId() === null)
			{
				$eventConnection = $context->getEventConnection();
				if ($eventConnection !== null)
				{
					$qm->mapperFactory->getEventConnection()->update(
						$eventConnection->setLastSyncStatus(Dictionary::SYNC_STATUS['success'])
					);
				}

				continue;
			}

			$factory = FactoryBuilder::create($connection->getVendor()->getCode(), $connection, $context);
			$syncManager = new VendorSynchronization($factory);
			$result = null;

			try
			{
				switch ($queueItem['SYNC_STATUS'])
				{
					case Dictionary::SYNC_STATUS['create']:
						$result = $syncManager->createEvent($event, $context);
						break;
					case Dictionary::SYNC_STATUS['recreate']:
						$result = $syncManager->deleteEvent($event, $context);
						// TODO: create eventConnection with status "create"
						$result = $syncManager->createEvent($event, $context);
						break;
					case Dictionary::SYNC_STATUS['update']:
						$result = $syncManager->updateEvent($event, $context);
						break;
					case Dictionary::SYNC_STATUS['delete']:
						$result = $syncManager->deleteEvent($event, $context);
						break;
				}
			}
			catch (Exception $e)
			{
			}

			$eventLink = $qm->mapperFactory->getEventConnection()->getMap(
				[
					'=EVENT_ID' => $event->getId(),
					'=CONNECTION_ID' => $factory->getConnection()->getId(),
				]
			)->fetch();

			if (!is_null($eventLink))
			{
				$retryCount = $eventLink->getRetryCount() + 1;
				$currentNextSyncTry = $connection->getNextSyncTry();
				if ($result && $result->isSuccess())
				{
					$resultData = $result->getData();

					if (
						is_array($resultData)
						&& (isset($resultData[$factory->getConnection()->getVendor()->getCode()])
							&& $resultData[$factory->getConnection()->getVendor()->getCode()]['status']
							=== Dictionary::SYNC_STATUS['success']
							|| ($resultData['status'] ?? null) === Dictionary::SYNC_STATUS['success'])
					)
					{
						$eventLink->setLastSyncStatus(Dictionary::SYNC_STATUS['success']);
						$retryCount = 0;
						$currentNextSyncTry = null;
					}
				}

				if (
					$eventLink->getLastSyncStatus() !== Dictionary::SYNC_STATUS['success']
					&& $retryCount > self::MAX_RETRY_COUNT
				)
				{
					$eventLink->setLastSyncStatus(Dictionary::SYNC_STATUS['failed']);
				}

				$eventLink->setRetryCount($retryCount);
				$qm->mapperFactory->getEventConnection()->update($eventLink);
			}
			else
			{
				$retryCount = 0;
				$currentNextSyncTry = null;
			}

			$connection->setNextSyncTry(
				self::prepareNextSyncTry(
					$currentNextSyncTry,
					$retryCount
				)
			);
		}

		$qm->saveConnections();

		return "\\Bitrix\\Calendar\\Sync\\Managers\\EventQueueManager::checkEvents();";
	}

	public static function createInstance(): EventQueueManager
	{
		return new self();
	}

	/**
	 * @return \CDBResult|false|void
	 */
	private static function getEventListDb()
	{
		global $DB;
		$sqlQuery = "SELECT "
			. " e.SECTION_ID,"
			. " ec.ID as EVENT_CONNECTION_ID,"
			. " ec.EVENT_ID,"
			. " ec.ENTITY_TAG,"
			. " ec.VENDOR_VERSION_ID,"
			. " ec.CONNECTION_ID,"
			. " ec.VENDOR_EVENT_ID,"
			. " ec.VERSION,"
			. " ec.SYNC_STATUS,"
			. " ec.RETRY_COUNT,"
			. " con.*"
			. " FROM b_calendar_event e"
			. " INNER JOIN b_calendar_event_connection ec ON ec.EVENT_ID = e.ID "
			. " INNER JOIN b_calendar_section s ON s.ID = e.SECTION_ID "
			. " INNER JOIN b_dav_connections con ON con.ID = ec.CONNECTION_ID "
			. " INNER JOIN b_calendar_section_connection sc ON sc.SECTION_ID = e.SECTION_ID "
			. " WHERE "
			. " ec.SYNC_STATUS <> '" . Dictionary::SYNC_STATUS['success'] . "'"
			. " and ec.SYNC_STATUS <> '" . Dictionary::SYNC_STATUS['failed'] . "'"
			. " and s.ACTIVE = 'Y' and sc.ACTIVE = 'Y' and sc.CONNECTION_ID = con.ID"
			. " and con.NEXT_SYNC_TRY <= NOW()"
			. " ORDER BY ec.RETRY_COUNT ASC"
			. " LIMIT " . self::CHECK_ENTRY_LIMIT;

		return $DB->Query($sqlQuery);
	}

	private function getConnectionForQueueItem(array $queueItem): Connection
	{
		$connectionId = (int)$queueItem['CONNECTION_ID'];
		if (!isset($this->connectionList[$connectionId]))
		{
			$this->connectionList[$connectionId] = (new BuilderConnectionFromArray($queueItem))->build();
		}

		return $this->connectionList[$connectionId];
	}

	private function prepareEventContext(array $params): EventContext
	{
		$queueItem = $params['queueItem'];

		$context = new Context(
			[
				'connection' => $params['connection'],
			]
		);

		$eventLink = (new EventConnection())
			->setId($queueItem['EVENT_CONNECTION_ID'])
			->setEntityTag($queueItem['ENTITY_TAG'])
			->setVendorVersionId($queueItem['VENDOR_VERSION_ID'])
			->setRetryCount($queueItem['RETRY_COUNT'])
			->setLastSyncStatus($queueItem['SYNC_STATUS'])
			->setVendorEventId($queueItem['VENDOR_EVENT_ID'])
			->setData(json_decode($queueItem['DATA'] ?? ''))
			->setVersion((int)$queueItem['VERSION'])
			->setConnection($params['connection'])
			->setEvent($params['event']);

		$sectionLink = $this->mapperFactory->getSectionConnection()->getMap(
			[
				'=SECTION_ID' => (int)$queueItem['SECTION_ID'],
				'=CONNECTION_ID' => (int)$queueItem['CONNECTION_ID'],
			]
		)->fetch();

		$context = (new EventContext())->merge($context)->setEventConnection($eventLink)->setSectionConnection(
				$sectionLink
			);

		return $context;
	}

	/**
	 * @param Date|null $currentNextSyncTime
	 * @param int $retryCount
	 *
	 * @return Date
	 *
	 * @throws ObjectException
	 */
	private static function prepareNextSyncTry(?Date $currentNextSyncTime, int $retryCount): Date
	{
		$nextSyncTime = new Date(new Type\DateTime());
		if ($retryCount > self::SHIFT_DATE_RETRY_COUNT)
		{
			$nextSyncTime = $nextSyncTime->add('+1 day');
		}

		if (!is_null($currentNextSyncTime) && $currentNextSyncTime->getTimestamp() > $nextSyncTime->getTimestamp())
		{
			$nextSyncTime = $currentNextSyncTime;
		}

		return $nextSyncTime;
	}

	private function saveConnections()
	{
		foreach ($this->connectionList as $connectionId => $connection)
		{
			try
			{
				$this->mapperFactory->getConnection()->update($connection);
			}
			catch (Exception $e)
			{
			}
		}
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit