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/office365/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

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

namespace Bitrix\Calendar\Sync\Office365;

use Bitrix\Calendar\Core\Base\BaseException;
use Bitrix\Calendar\Sync\Dictionary;
use Bitrix\Calendar\Sync\Exceptions\ApiException;
use Bitrix\Calendar\Sync\Exceptions\AuthException;
use Bitrix\Calendar\Sync\Exceptions\ConflictException;
use Bitrix\Calendar\Sync\Exceptions\GoneException;
use Bitrix\Calendar\Sync\Exceptions\NotFoundException;
use Bitrix\Calendar\Sync\Exceptions\PreconditionFailedException;
use Bitrix\Calendar\Sync\Exceptions\RemoteAccountException;
use Bitrix\Calendar\Sync\Internals\ContextInterface;
use Bitrix\Calendar\Sync\Internals\HasContextTrait;
use Bitrix\Calendar\Sync\Office365\Dto\EventDto;
use Bitrix\Calendar\Sync\Office365\Dto\SectionDto;
use Bitrix\Calendar\Sync\Connection\SectionConnection;
use Bitrix\Main\ArgumentException;
use Bitrix\Main\ArgumentNullException;
use Bitrix\Main\LoaderException;
use CCalendar;
use Generator;

class ApiService
{
	use HasContextTrait;

	private const CALENDAR_SELECT_FIELDS = [
		'id',
		'name',
		'color',
		'hexColor',
		'isDefaultCalendar',
		'changeKey',
		'canShare',
		'canViewPrivateItems',
		'canEdit',
		'isTallyingResponses',
		'isRemovable',
		'owner',
	];

	/** @var Helper */
	private $helper;
	/** @var ApiClient */
	private $apiClient;

	/**
	 * @param ContextInterface $context
	 *
	 * @throws BaseException
	 * @throws LoaderException
	 * @throws RemoteAccountException
	 * @throws AuthException
	 */
	public function __construct(ContextInterface $context)
	{
		/** @var Office365Context $context */
		$this->context = $context;
		$this->apiClient = $this->context->getApiClient();
		$this->helper = $this->context->getHelper();
	}

	/**
	 * @param array $params
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function getCalendarList(array $params): array
	{
		$selectParams = self::getCalendarSelectParams();

		$params = array_merge($selectParams, $params);

		$response = $this->apiClient->get('me/calendars', $params);

		return (array)$response['value'];
	}

	/**
	 * @param array $params
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function getEventList(array $params): array
	{
		$response = $this->apiClient->get(
			'me/calendars/' . $params['filter']['section_id'] . '/events',
			$params
		);

		return (array) $response['value'];
	}

	/**
	 * @param SectionDto $sectionDto
	 *
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function createSection(SectionDto $sectionDto): array
	{
		$selectParams = self::getCalendarSelectParams();

		$selectQuery = http_build_query($selectParams);

		return $this->apiClient->post('me/calendars?' . $selectQuery, array_filter($sectionDto->toArray()));
	}

	/**
	 * @param SectionDto $sectionDto
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function updateSection(SectionDto $sectionDto): array
	{
		return $this->apiClient->patch('me/calendars/' . $sectionDto->id, array_filter($sectionDto->toArray()));
	}

	/**
	 * @param EventDto $eventDto
	 * @param string $sectionId
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function createEvent(EventDto $eventDto, string $sectionId): array
	{
		return $this->apiClient->post(
			'me/calendars/' . $sectionId . '/events',
			array_filter($eventDto->toArray(true), static function ($val) {
				return $val !== [] && $val !== null;
			})
		);
	}

	/**
	 * @param SectionConnection $sectionConnection
	 *
	 * @return Generator
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws ArgumentNullException
	 * @throws BaseException
	 * @throws ConflictException
	 * @throws NotFoundException
	 */
	public function getCalendarDelta(SectionConnection $sectionConnection): Generator
	{
		$baseUri = 'me/calendars/' . $sectionConnection->getVendorSectionId() . '/calendarView/delta?';
		$breakingFlag = false;
		do {
			$uri = $this->getDeltaUri($sectionConnection, $baseUri);

			try
			{
				$response = $this->apiClient->get($uri);
				if (!empty($response))
				{
					$breakingFlag = $this->processResponseAfterDelta($sectionConnection, $response);
				}
				if (!empty($response['value']))
				{
					yield $response['value'];
				}
				else
				{
					break;
				}
			}
			catch(GoneException $e)
			{
				if ($sectionConnection->getPageToken())
				{
					$sectionConnection->setPageToken(null);
				}
				elseif ($sectionConnection->getSyncToken())
				{
					$sectionConnection->setSyncToken(null);
				}
			}
		}
		while(!$breakingFlag);
	}

	/**
	 * @param string $uri
	 * @param string $name
	 *
	 * @return string|null
	 */
	private function getUriParam(string $uri, string $name): ?string
	{
		$result = null;
		if ($urlData = parse_url($uri))
		{
			parse_str($urlData['query'], $params);
			$result = $params[$name] ?? null;
		}

		return $result;
	}

	/**
	 * @param array $params
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function getEvent(array $params): array
	{
		return $this->apiClient->get(
			'me/events/' . $params['filter']['event_id'],
			$params
		);
	}

	/**
	 * @param EventDto $eventDto
	 * @param string $vendorEventId
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function updateEvent(EventDto $eventDto, string $vendorEventId): array
	{
		if ($eventDto->isCancelled)
		{
			$response = $this->apiClient->post(
				'me/events/' . $vendorEventId . '/cancel',
				[
					'Comment' => 'Deleted from Bitrix',
				]
			);
		}
		else
		{
			try
			{
				$response = $this->apiClient->patch(
					'me/events/' . $vendorEventId,
					array_filter($eventDto->toArray(true), static function ($val) {
						return $val !== [] && $val !== null;
					})
				);
			}
			catch (NotFoundException|PreconditionFailedException $exception)
			{
				return [];
			}
		}

		return $response;
	}

	/**
	 * @param array $params
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function getEventInstances(array $params): array
	{
		return $this->apiClient->get(
			'me/events/' . $params['filter']['event_id'] . '/instances',
			[
				'startDateTime' => $params['filter']['from'],
				'endDateTime' => $params['filter']['to'],
			]
		);
	}

	/**
	 * @param string $vendorEventId
	 *
	 * @return void
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function deleteEvent(string $vendorEventId)
	{
		try
		{
			$this->apiClient->delete(
				'me/events/' . $vendorEventId,
			);
		}
		catch (NotFoundException $exception)
		{
			return;
		}
	}

	/**
	 * @param string $vendorSectionId
	 *
	 * @return void
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function deleteSection(string $vendorSectionId)
	{
		$this->apiClient->delete(
			'me/calendars/' . $vendorSectionId,
		);
	}

	/**
	 * @param string $vendorSectionId
	 * @param string $state
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function addSectionSubscription(string $vendorSectionId, string $state = ''): array
	{
		$data = [
			'changeType' => 'created,updated,deleted',
			'notificationUrl' => $this->getNotificationUrl(),
			'resource' => "me/calendars/$vendorSectionId/events",
			'expirationDateTime' => $this->getExpirationDateTime(),
			'clientState' => $state,
			'latestSupportedTlsVersion' => 'v1_2',
		];

		return $this->apiClient->post('subscriptions', $data);
	}

	/**
	 * @param string $subscriptionId
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 * @throws NotFoundException
	 */
	public function renewSectionSubscription(string $subscriptionId): array
	{
		return $this->apiClient->patch('subscriptions/' . $subscriptionId, [
			'expirationDateTime' => $this->getExpirationDateTime(),
		]);
	}

	/**
	 * @param string $subscriptionId
	 *
	 * @return array
	 *
	 * @throws ApiException
	 * @throws ArgumentException
	 * @throws AuthException
	 * @throws ConflictException
	 * @throws GoneException
	 */
	public function deleteSectionSubscription(string $subscriptionId): array
	{
		try
		{
			return $this->apiClient->delete('subscriptions/' . $subscriptionId);
		}
		catch (NotFoundException|AuthException $exception)
		{
			return [];
		}
	}

	/**
	 * @param SectionConnection $sectionConnection
	 * @param string $baseUri
	 * @return string
	 */
	public function getDeltaUri(SectionConnection $sectionConnection, string $baseUri): string
	{
		if ($sectionConnection->getPageToken())
		{
			$uri = $baseUri . '$skiptoken=' . $sectionConnection->getPageToken();
		}
		elseif ($sectionConnection->getSyncToken())
		{
			$uri = $baseUri . '$deltatoken=' . $sectionConnection->getSyncToken();
		}
		else
		{
			$interval = $this->helper->getDeltaInterval();
			$uri = $baseUri . 'startDateTime=' . $interval['from']->format($this->helper::TIME_FORMAT_LONG)
				. '&endDateTime=' . $interval['to']->format($this->helper::TIME_FORMAT_LONG);
		}
		return $uri;
	}

	/**
	 * Temporary solution for fix http://jabber.bx/view.php?id=221156
	 *
	 * Without select request returns 500 response due to the
	 * `allowedOnlineMeetingProviders` and `defaultOnlineMeetingProvider` fields
	 *
	 * @see https://learn.microsoft.com/en-us/answers/questions/2279133/getting-500-response-errors-to-get-me-calendars-al
	 */
	public static function getCalendarSelectParams(): array
	{
		return [
			'$select' => implode(',', self::CALENDAR_SELECT_FIELDS),
		];
	}

	/**
	 * @param SectionConnection $sectionConnection
	 * @param array $response
	 *
	 * @return bool
	 */
	private function processResponseAfterDelta(SectionConnection $sectionConnection, array $response): bool
	{
		$sectionConnection->setLastSyncStatus(Dictionary::SYNC_STATUS['success']);
		$breakingFlag = true;

		if ($token = $this->getPageToken($response))
		{
			$sectionConnection->setPageToken($token);
			$breakingFlag = false;
		}
		elseif ($token = $this->getSyncToken($response))
		{
			$sectionConnection->setPageToken(null);
			$sectionConnection->setSyncToken($token);
		}
		else
		{
			$sectionConnection->setPageToken(null);
			$sectionConnection->setSyncToken(null);
		}

		return $breakingFlag;
	}

	/**
	 * @param array $response
	 *
	 * @return string|null
	 */
	private function getPageToken(array $response): ?string
	{
		return !empty($response['@odata.nextLink'])
			? $this->getUriParam($response['@odata.nextLink'], '$skiptoken')
			: null
			;
	}
	/**
	 * @param array $response
	 *
	 * @return string|null
	 */
	private function getSyncToken(array $response): ?string
	{
		return !empty($response['@odata.deltaLink'])
			? $this->getUriParam($response['@odata.deltaLink'], '$deltatoken')
			: null
			;
	}

	/**
	 * @return string
	 */
	private function getNotificationUrl(): string
	{
		return str_replace('http:', 'https:', CCalendar::GetServerPath())
			. $this->helper::PUSH_PATH;
	}

	/**
	 * @return string
	 */
	private function getExpirationDateTime(): string
	{
		$time = time() + 70 * 60 * 60;
		return date("c", $time);
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit