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/calendar/lib/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/calendar/lib/util.php
<?php
namespace Bitrix\Calendar;

use Bitrix\Calendar\Core\Event\Tools\Dictionary;
use Bitrix\Calendar\Integration\Pull\PushCommand;
use Bitrix\Calendar\Integration\Pull\PushService;
use Bitrix\Calendar\Sync\Util\MsTimezoneConverter;
use Bitrix\Extranet\Service\ServiceContainer;
use Bitrix\Main;
use Bitrix\Main\Application;
use Bitrix\Main\Loader;
use Bitrix\Main\LoaderException;
use Bitrix\Main\Localization\LanguageTable;
use Bitrix\Main\Localization\Loc;
use Bitrix\Main\Text\Emoji;
use Bitrix\Main\Type\Date;
use Bitrix\Main\Type\DateTime;
use COption;

class Util
{
	public const USER_SELECTOR_CONTEXT = "CALENDAR";
	public const USER_FIELD_ENTITY_ID = 'CALENDAR_EVENT';
	public const LIMIT_NUMBER_BANNER_IMPRESSIONS = 3;
	public const DATETIME_PHP_FORMAT = 'Y-m-d H:i:sP';
	public const VERSION_DIFFERENCE = 1;
	public const DEFAULT_TIMEZONE = "UTC";

	private static $requestUid = '';
	private static $userAccessCodes = [];
	private static $pathCache = [];
	private static $isRussian = null;

	/**
	 * @param $managerId
	 * @param $userId
	 * @return bool
	 */
	public static function isManagerForUser($managerId, $userId): bool
	{
		return in_array('IU'.$userId, self::getUserAccessCodes($managerId));
	}

	/**
	 * @return bool
	 * @throws Main\ArgumentNullException
	 * @throws Main\ArgumentOutOfRangeException
	 */
	public static function isSectionStructureConverted(): bool
	{
		return \Bitrix\Main\Config\Option::get('calendar', 'sectionStructureConverted', 'N') === 'Y';
	}

	/**
	 * @param $date
	 * @param bool $round
	 * @param bool $getTime
	 * @return false|float|int
	 */
	public static function getTimestamp($date, $round = true, $getTime = true)
	{
		$timestamp = MakeTimeStamp($date, \CSite::getDateFormat($getTime ? "FULL" : "SHORT"));

		return $round ? (round($timestamp / 60) * 60) : $timestamp;
	}

	/**
	 * @param string|null $timeZone
	 * @return bool
	 */
	public static function isTimezoneValid(?string $timeZone): bool
	{
		return (!is_null($timeZone) && $timeZone !== 'false' && in_array($timeZone, timezone_identifiers_list(), true));
	}

	/**
	 * @param string|null $tz
	 * @return \DateTimeZone
	 */
	public static function prepareTimezone(?string $tz = null): \DateTimeZone
	{
		if (!$tz)
		{
			return new \DateTimeZone(self::DEFAULT_TIMEZONE);
		}

		if (self::isTimezoneValid($tz))
		{
			return new \DateTimeZone($tz);
		}

		if ($timezones = MsTimezoneConverter::getValidateTimezones($tz))
		{
			return new \DateTimeZone($timezones[0]);
		}

		return new \DateTimeZone(self::getServerTimezoneName());
	}

	/**
	 * @param string|null $date
	 * @param bool $fullDay
	 * @param string|null $tz
	 * @return Date
	 * @throws Main\ObjectException
	 */
	public static function getDateObject(string $date = null, ?bool $fullDay = true, ?string $tz = 'UTC'): Date
	{
		$preparedDate = $date;
		if ($date)
		{
			$timestamp = \CCalendar::Timestamp($date, false, !$fullDay);
			$preparedDate = \CCalendar::Date($timestamp, !$fullDay);
		}

		return $fullDay
			? new Date($preparedDate, Date::convertFormatToPhp(FORMAT_DATE))
			: new DateTime($preparedDate, Date::convertFormatToPhp(FORMAT_DATETIME), Util::prepareTimezone($tz));
	}

	/**
	 * @return string
	 */
	public static function getUserSelectorContext(): string
	{
		return self::USER_SELECTOR_CONTEXT;
	}

	public static function checkRuZone(): bool
	{
		if (!is_null(self::$isRussian))
		{
			return self::$isRussian;
		}

		if (\Bitrix\Main\ModuleManager::isModuleInstalled('bitrix24'))
		{
			self::$isRussian = (\CBitrix24::getPortalZone() === 'ru');
		}
		else
		{
			$iterator = LanguageTable::getList([
				'select' => ['ID'],
				'filter' => ['=ID' => 'ru', '=ACTIVE' => 'Y']
			]);

			$row = $iterator->fetch();
			if (empty($row))
			{
				self::$isRussian = false;
			}
			else
			{
				$iterator = LanguageTable::getList([
					'select' => ['ID'],
					'filter' => ['@ID' => ['ua', 'by', 'kz'], '=ACTIVE' => 'Y'],
					'limit' => 1
				]);
				$row = $iterator->fetch();
				self::$isRussian = empty($row);
			}
		}

		return self::$isRussian;
	}

	public static function convertEntitiesToCodes($entityList = [])
	{
		$codeList = [];
		if (is_array($entityList))
		{
			foreach($entityList as $entity)
			{
				if ($entity['entityId'] === 'meta-user' && $entity['id'] === 'all-users')
				{
					$codeList[] = 'UA';
				}
				elseif ($entity['entityId'] === 'user')
				{
					$codeList[] = 'U'.$entity['id'];
				}
				elseif ($entity['entityId'] === 'project' || $entity['entityId'] === 'project-roles')
				{
					$codeList[] = 'SG'.$entity['id'];
				}
				elseif ($entity['entityId'] === 'department')
				{
					$codeList[] = 'DR'.$entity['id'];
				}
			}
		}
		return $codeList;
	}

	public static function convertCodesToEntities($codeList = [])
	{
		$entityList = [];
		if (is_array($codeList))
		{
			foreach($codeList as $code)
			{
				if ($code === 'UA')
				{
					$entityList[] = [
						'entityId' => 'meta-user',
						'id' => 'all-users'
					];
				}
				elseif (mb_substr($code, 0, 1) == 'U')
				{
					$entityList[] = [
						'entityId' => 'user',
						'id' => intval(mb_substr($code, 1))
					];
				}
				if (mb_substr($code, 0, 2) == 'DR')
				{
					$entityList[] = [
						'entityId' => 'department',
						'id' => intval(mb_substr($code, 2))
					];
				}
				elseif (preg_match('/^SG([0-9]+)_?([AEKMO])?$/', $code, $match) && isset($match[2]))
				{
					// todo May need to be removed/rewrite after creating new roles in projects.
					$entityList[] = [
						'entityId' => 'project-roles',
						'id' => mb_substr($code, 2)
					];
				}
				elseif (mb_substr($code, 0, 2) == 'SG')
				{
					$entityList[] = [
						'entityId' => 'project',
						'id' => intval(mb_substr($code, 2))
					];
				}
			}
		}

		return $entityList;
	}

	public static function getUsersByEntityList($entityList, $fetchUsers = false)
	{
		return \CCalendar::GetDestinationUsers(self::convertEntitiesToCodes($entityList), $fetchUsers);
	}


	public static function getDefaultEntityList($userId, $type, $ownerId)
	{
		$entityList = [['entityId' => 'user', 'id' => $userId]];
		if ($type === 'user' && $ownerId !== $userId)
		{
			$entityList[] = ['entityId' => 'user', 'id' => $ownerId];
		}
		else if($type === 'group')
		{
			$entityList[] = ['entityId' => 'project', 'id' => $ownerId];
		}
		return $entityList;
	}

	/**
	 * @param array|null $codeAttendees
	 * @param string $stringWrapper
	 * @return array
	 * @throws Main\ArgumentException
	 * @throws Main\ObjectPropertyException
	 * @throws Main\SystemException
	 */
	public static function getAttendees(array $codeAttendees = null, string $stringWrapper = ''): array
	{
		if (empty($codeAttendees))
		{
			return [];
		}

		$userIdList = [];
		$userList = [];

		foreach ($codeAttendees as $codeAttend)
		{
			if (mb_strpos($codeAttend, 'U') === 0)
			{
				$userId = (int)(mb_substr($codeAttend, 1));
				$userIdList[] = $userId;
			}
		}

		if (!empty($userIdList))
		{
			$res = \Bitrix\Main\UserTable::getList(array(
				'filter' => [
					'=ID' => $userIdList,
				],
				'select' => ['NAME', 'LAST_NAME'],
			));

			while ($user = $res->fetch())
			{
				$userList[] = addcslashes($stringWrapper . $user['NAME'].' '.$user['LAST_NAME'] . $stringWrapper, "()");
			}
		}

		return $userList;
	}

	/**
	 * @param int $userId
	 * @return bool
	 * @throws Main\ArgumentException
	 * @throws Main\LoaderException
	 * @throws Main\ObjectPropertyException
	 * @throws Main\SystemException
	 */
	public static function isExtranetUser(int $userId): bool
	{
		if (Loader::includeModule('intranet'))
		{
			$userDb = \Bitrix\Intranet\UserTable::getList([
				'filter' => [
					'ID' => $userId,
				],
				'select' => [
					'USER_TYPE',
				]
			]);

			$user = $userDb->fetch();
			return $user['USER_TYPE'] === 'extranet';
		}

		return false;
	}

	public static function isCollabUser(int $userId): bool
	{
		return Loader::includeModule('extranet')
		 	&& ServiceContainer::getInstance()->getCollaberService()->isCollaberById($userId);
	}

	/**
	 * @param int $eventId
	 * @return array|null
	 * @throws Main\ArgumentException
	 * @throws Main\ObjectPropertyException
	 * @throws Main\SystemException
	 */
	public static function getEventById(int $eventId): ?array
	{
		$eventDb = Internals\EventTable::getList([
			'filter' => [
				'=ID' => $eventId,
			],
		]);

		if ($event = $eventDb->fetch())
		{
			if (!empty($event['NAME']))
			{
				$event['NAME'] = Emoji::decode($event['NAME']);
			}
			if (!empty($event['DESCRIPTION']))
			{
				$event['DESCRIPTION'] = Emoji::decode($event['DESCRIPTION']);
			}
			if (!empty($event['LOCATION']))
			{
				$event['LOCATION'] = Emoji::decode($event['LOCATION']);
			}
			return $event;
		}

		return null;
	}

	/**
	 * @param PushCommand $command
	 * @param int $userId
	 * @param array $params
	 * @return void
	 * @throws LoaderException
	 */
	public static function addPullEvent(PushCommand $command, int $userId, array $params = []): void
	{
		if (!Loader::includeModule("pull"))
		{
			return;
		}

		if (
			in_array($command->value, [
				PushCommand::EditEvent->value,
				PushCommand::DeleteEvent->value,
				PushCommand::SetMeetingStatus->value,
			], true)
		)
		{
			PushService::addEventByTag('calendar-planner-'.$userId, [
				'module_id' => PushService::MODULE_ID,
				'command' => $command->value,
				'params' => $params
			]);

			if (isset($params['fields']['CAL_TYPE']) && $params['fields']['CAL_TYPE'] === 'location')
			{
				PushService::addEventByTag('calendar-location', [
					'module_id' => PushService::MODULE_ID,
					'command' => "{$command->value}_location",
					'params' => [
						'fields' => [
							'DATE_FROM' => $params['fields']['DATE_FROM'],
							'DATE_TO' => $params['fields']['DATE_TO'],
							'EXDATE' => $params['fields']['EXDATE'],
						],
					],
				]);
			}
		}

		if (
			isset($params['fields']['SECTION_OWNER_ID'])
			&& (int)$params['fields']['SECTION_OWNER_ID'] !== $userId
			&& in_array($command->value, [
				PushCommand::EditEvent->value,
				PushCommand::DeleteEvent->value,
				PushCommand::SetMeetingStatus->value,
			], true)
		)
		{
			PushService::addEvent((int)$params['fields']['SECTION_OWNER_ID'], [
				'module_id' => PushService::MODULE_ID,
				'command' => $command->value,
				'params' => $params,
			]);
		}

		PushService::addEvent($userId, [
			'module_id' => PushService::MODULE_ID,
			'command' => $command->value,
			'params' => $params,
		]);
	}

	/**
	 * @param int $currentUserId
	 * @param array $userIdList
	 *
	 * @return void
	 */
	public static function initPlannerPullWatches(int $currentUserId, array $userIdList = []): void
	{
		if (Loader::includeModule("pull"))
		{
			foreach($userIdList as $userId)
			{
				if ((int)$userId !== $currentUserId)
				{
					\CPullWatch::Add($currentUserId, 'calendar-planner-'.$userId);
				}
			}
		}
	}

	public static function getUserFieldsByEventId(int $eventId): array
	{
		global $DB;
		$result = [];
		$strSql = "SELECT * from b_uts_calendar_event WHERE VALUE_ID=" . $eventId;
		$ufDb = $DB->query($strSql);

		while ($uf = $ufDb->fetch())
		{
			$result[] = [
				'crm' => unserialize($uf['UF_CRM_CAL_EVENT'], ['allowed_classes' => false]),
				'webdav' => unserialize($uf['UF_WEBDAV_CAL_EVENT'], ['allowed_classes' => false]),
			];
		}

		return $result;
	}

	/**
	 * @return string
	 */
	public static function getServerTimezoneName(): string
	{
		return (new \DateTime())->getTimezone()->getName();
	}

	/**
	 * @return int
	 */
	public static function getServerOffsetUTC(): int
	{
		return (new \DateTime())->getOffset();
	}

	/**
	 * @param string|null $tz
	 * @param null $date
	 * @return int
	 * @throws \Exception
	 */
	public static function getTimezoneOffsetFromServer(?string $tz = 'UTC', $date = null): int
	{
		if ($date instanceof Date)
		{
			$timestamp = $date->format(self::DATETIME_PHP_FORMAT);
		}
		elseif ($date === null)
		{
			$timestamp = 'now';
		}
		else
		{
			$timestamp = "@".(int)$date;
		}

		$date = new \DateTime($timestamp, self::prepareTimezone($tz));

		return $date->getOffset() - self::getServerOffsetUTC();
	}

	/**
	 * @param string $requestUid
	 */
	public static function setRequestUid(string $requestUid = ''): void
	{
		self::$requestUid = $requestUid;
	}

	/**
	 * @return string
	 */
	public static function getRequestUid(): string
	{
		return self::$requestUid;
	}

	/**
	 * @param int $userId
	 * @return array
	 */
	public static function getUserAccessCodes(int $userId): array
	{
		global $USER;
		$userId = (int)$userId;
		if (!$userId)
		{
			$userId = \CCalendar::GetCurUserId();
		}

		if (!isset(self::$userAccessCodes[$userId]))
		{
			$codes = [];
			$r = \CAccess::GetUserCodes($userId);
			while($code = $r->Fetch())
			{
				$codes[] = $code['ACCESS_CODE'];
			}

			if (!in_array('G2', $codes))
			{
				$codes[] = 'G2';
			}

			if (!in_array('AU', $codes) && $USER && (int)$USER->GetId() === $userId)
			{
				$codes[] = 'AU';
			}

			if(!in_array('UA', $codes) && $USER && (int)$USER->GetId() == $userId)
			{
				$codes[] = 'UA';
			}

			self::$userAccessCodes[$userId] = $codes;
		}

		return self::$userAccessCodes[$userId];
	}

	/**
	 * @param int|null $ownerId
	 * @param string|null $type
	 *
	 * @return string
	 */
	public static function getPathToCalendar(?int $ownerId, ?string $type): string
	{
		$key = $type . $ownerId;
		if (!isset(self::$pathCache[$key]) || !is_string(self::$pathCache[$key]))
		{
			if ($type === Dictionary::CALENDAR_TYPE['user'] || $type === Dictionary::CALENDAR_TYPE['open_event'])
			{
				$path = \COption::GetOptionString(
					'calendar',
					'path_to_user_calendar',
					\COption::getOptionString('socialnetwork', 'user_page', "/company/personal/")
					. "user/#user_id#/calendar/"
				);
			}
			else if ($type === Dictionary::CALENDAR_TYPE['group'])
			{
				$path = \COption::GetOptionString(
					'calendar',
					'path_to_group_calendar',
					\COption::getOptionString('socialnetwork', 'workgroups_page', "/workgroups/")
					. "group/#group_id#/calendar/"
				);
			}
			else if (in_array($type, ['company', 'company_calendar', 'calendar_company'], true))
			{
				$path = '/calendar/';
			}
			else
			{
				$settings = \CCalendar::GetSettings();
				$path = $settings['path_to_type_' . $type] ?? null;
			}

			if (!\COption::GetOptionString('calendar', 'pathes_for_sites', true))
			{
				$siteId = \CCalendar::GetSiteId();
				$pathList = \CCalendar::GetPathes();
				if (isset($pathList[$siteId]))
				{
					if ($type === Dictionary::CALENDAR_TYPE['user'] && !empty($pathList[$siteId]['path_to_user_calendar']))
					{
						$path = $pathList[$siteId]['path_to_user_calendar'];
					}
					else if ($type === Dictionary::CALENDAR_TYPE['group'] && !empty($pathList[$siteId]['path_to_group_calendar']))
					{
						$path = $pathList[$siteId]['path_to_group_calendar'];
					}
					else if (!empty($pathList[$siteId]['path_to_type_company_calendar']) && in_array($type, ['company', 'company_calendar', 'calendar_company'], true))
					{
						$path = $pathList[$siteId]['path_to_type_company_calendar'];
					}
					else if (!empty($pathList[$siteId]['path_to_type_' . $type]))
					{
						$path = $pathList[$siteId]['path_to_type_' . $type];
					}
				}
			}

			if (!is_string($path))
			{
				$path =  '';
			}

			// substitute user=0 for links to open events
			if (!empty($path))
			{
				if ($ownerId > 0)
				{
					if ($type === Dictionary::CALENDAR_TYPE['user'])
					{
						$path = str_replace(['#user_id#', '#USER_ID#'], $ownerId, $path);
					}
					elseif ($type === Dictionary::CALENDAR_TYPE['group'])
					{
						$path = str_replace(['#group_id#', '#GROUP_ID#'], $ownerId, $path);
					}
				}
				elseif ($type === Dictionary::CALENDAR_TYPE['open_event'])
				{
					$path = str_replace(['#user_id#', '#USER_ID#'], $ownerId, $path);
				}
			}

			self::$pathCache[$key] = $path;
		}

		return self::$pathCache[$key];
	}

	/**
	 * @return string
	 */
	public static function getServerName(): string
	{
		return COption::getOptionString('main', 'server_name', Application::getInstance()->getContext()->getServer()->getServerName());
	}

	/**
	 * @param int $second
	 *
	 * @return int[]
	 */
	public static function secondsToDayHoursMinutes(int $second): array
	{
		$day = $second / 24 / 3600;
        $hours = $second / 3600 - (int)$day * 24;
        $min = $second / 60 - (int)$day * 24 * 60 - (int)$hours * 60;

		return [
			'days' => (int)$day,
			'hours' => (int)$hours,
			'minutes' => (int)$min
		];
	}

	/**
	 * @param int $minutes
	 *
	 * @return int[]
	 */
	public static function minutesToDayHoursMinutes(int $minutes): array
	{
		$day = $minutes / 24 / 60;
		$hours = $minutes / 60 - (int)$day * 24;
		$min = $minutes - (int)$day * 24 * 60 - (int)$hours * 60;

		return [
			'days' => (int)$day,
			'hours' => (int)$hours,
			'minutes' => (int)$min
		];
	}

	public static function getDateTimestamp(?string $dateFrom, ?string $timezone): ?int
	{
		if (!$dateFrom || !$timezone)
		{
			return null;
		}

		$date =  new \Bitrix\Calendar\Core\Base\Date(
			Util::getDateObject(
				$dateFrom,
				false,
				$timezone
			)
		);

		return $date->getTimestamp();
	}

	public static function formatDateTimeTimestamp(int $timestamp, string $timezoneName): string
	{
		$timezone = new \DateTimeZone($timezoneName);
		$dateTimeFormat = Date::convertFormatToPhp(FORMAT_DATETIME);

		return (new \DateTime('now', $timezone))
			->setTimestamp($timestamp)
			->format($dateTimeFormat)
		;
	}

	public static function formatDateTimeTimestampUTC(int $timestamp): string
	{
		$dateTimeFormat = Date::convertFormatToPhp(FORMAT_DATETIME);

		return gmdate($dateTimeFormat, $timestamp);
	}

	public static function formatDateTimestampUTC(int $timestamp): string
	{
		$dateFormat = Date::convertFormatToPhp(FORMAT_DATE);

		return gmdate($dateFormat, $timestamp);
	}

	public static function getTimezoneOffsetUTC(string $timezoneName): int
	{
		$utc = new \DateTimeZone('UTC');

		return (new \DateTimeZone($timezoneName))->getOffset(new \DateTime('now', $utc));
	}

	public static function getDateTimestampUtc(DateTime $date, ?string $eventTimezone = null): int
	{
		$dateTimezone = $date->getTimeZone()->getName();
		$dateTimestampUTC = $date->getTimestamp() + \CCalendar::GetTimezoneOffset($dateTimezone);
		$eventOffsetUTC = \CCalendar::GetTimezoneOffset($eventTimezone);

		return $dateTimestampUTC - $eventOffsetUTC;
	}

	public static function formatEventDateTime(DateTime $dateTime): string
	{
		$culture = Main\Application::getInstance()->getContext()->getCulture();
		$dayMonthFormat = Main\Type\Date::convertFormatToPhp($culture->getDateFormat());
		$timeFormat = $culture->get('SHORT_TIME_FORMAT');

		$eventDate = FormatDate($dayMonthFormat, $dateTime->getTimestamp());
		$eventTime = FormatDate($timeFormat, $dateTime->getTimestamp());

		return "$eventDate $eventTime";
	}

	public static function getTimezoneHint(int $userId, array $event): string
	{
		$skipTime = $event['DT_SKIP_TIME'] === "Y";
		$timezoneHint = '';
		if (
			!$skipTime
			&& (
				(int)$event['~USER_OFFSET_FROM'] !== 0
				|| (int)$event['~USER_OFFSET_TO'] !== 0
				|| $event['TZ_FROM'] !== $event['TZ_TO']
				|| $event['TZ_FROM'] !== \CCalendar::GetUserTimezoneName($userId)
			)
		)
		{
			if ($event['TZ_FROM'] === $event['TZ_TO'])
			{
				$timezoneHint = \CCalendar::GetFromToHtml(
					\CCalendar::Timestamp($event['DATE_FROM']),
					\CCalendar::Timestamp($event['DATE_TO']),
					false,
					$event['DT_LENGTH']
				);
				if ($event['TZ_FROM'])
				{
					$timezoneHint .= ' (' . $event['TZ_FROM'] . ')';
				}
			}
			else
			{
				$timezoneHint = Loc::getMessage('EC_VIEW_DATE_FROM_TO', array('#DATE_FROM#' => $event['DATE_FROM'].' ('.$event['TZ_FROM'].')', '#DATE_TO#' => $event['DATE_TO'].' ('.$event['TZ_TO'].')'));
			}
		}

		return $timezoneHint;
	}

	public static function formatEventDate(DateTime $dateTime): string
	{
		$culture = Main\Application::getInstance()->getContext()->getCulture();
		$dayMonthFormat = Main\Type\Date::convertFormatToPhp($culture->getDateFormat());

		return FormatDate($dayMonthFormat, $dateTime->getTimestamp());
	}

	public static function doIntervalsIntersect($from1, $to1, $from2, $to2): bool
	{
		return self::oneIntervalIntersectsAnother($from1, $to1, $from2, $to2)
			|| self::oneIntervalIntersectsAnother($from2, $to2, $from1, $to1);
	}

	public static function oneIntervalIntersectsAnother($from1, $to1, $from2, $to2): bool
	{
		$startsInside = $from2 <= $from1 && $from1 < $to2;
		$endsInside = $from2 < $to1 && $to1 <= $to2;
		$startsBeforeEndsAfter = $from1 <= $from2 && $to1 >= $to2;

		return $startsInside || $endsInside || $startsBeforeEndsAfter;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit