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/im/lib/update/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/im/lib/update/chatconfigconverter.php
<?php
namespace Bitrix\Im\Update;

use Bitrix\Im\Configuration\Configuration;
use Bitrix\Im\Configuration\Department;
use Bitrix\Im\Configuration\General;
use Bitrix\Im\Configuration\Manager;
use Bitrix\Im\Configuration\Notification;
use Bitrix\Im\Model\OptionAccessTable;
use Bitrix\Im\Model\OptionGroupTable;
use Bitrix\Im\Model\OptionStateTable;
use Bitrix\Im\Model\OptionUserTable;
use Bitrix\Im\Model\StatusTable;
use Bitrix\Main\Application;
use Bitrix\Main\Config\Option;
use Bitrix\Main\Loader;
use Bitrix\Main\ORM\Fields\Relations\Reference;
use Bitrix\Main\ORM\Query\Join;
use Bitrix\Main\Update\Stepper;
use Bitrix\Main\UserTable;

class ChatConfigConverter extends Stepper
{
	public const OPTION_NAME = 'im_chat_config_converter';
	protected static $moduleId = 'im';
	private const ITERATION_LIMIT = 500;

	private static $notifyDefaultSettings = [];
	private static $generalDefaultSettings = [];

	public function execute(array &$option)
	{
		if (!Loader::includeModule(self::$moduleId))
		{
			return false;
		}

		$configTruncate = Option::get(self::$moduleId, 'config_truncate', 'N');
		if ($configTruncate !== 'Y')
		{
			Option::set(self::$moduleId, 'migration_to_new_settings', 'N');

			$connection = Application::getConnection();
			$connection->query("TRUNCATE TABLE b_im_option_user");
			$connection->query("TRUNCATE TABLE b_im_option_state");
			$connection->query("TRUNCATE TABLE b_im_option_access");
			$connection->query("TRUNCATE TABLE b_im_option_group");

			Option::set(self::$moduleId, 'config_truncate', 'Y');
		}

		$params = Option::get(self::$moduleId, self::OPTION_NAME, '');
		$params = ($params !== '' ? @unserialize($params, ['allowed_classes' => false]) : []);
		$params = is_array($params) ? $params : [];

		$unconvertedUsers = Option::get(self::$moduleId, 'unconverted_settings_users', '');
		$unconvertedUsers = $unconvertedUsers !== '' ? @unserialize($unconvertedUsers, ['allowed_classes' => false]) : [];
		$unconvertedUsers = is_array($unconvertedUsers) ? $unconvertedUsers : [];

		if (empty($params))
		{
			Option::set(self::$moduleId, 'migration_to_new_settings', 'N');
			Configuration::cleanAllCache();
			$unconvertedUsers = [];

			$isIntranetIncluded = Loader::includeModule('intranet');

			$defaultGroupId = $this->getDefaultGroupId();
			if (!$defaultGroupId)
			{
				$defaultGroupId = Configuration::createDefaultPreset();
			}
			elseif ($isIntranetIncluded)
			{
				$this->updateDefaultAccessCode($defaultGroupId);
			}

			$userCount = UserTable::getCount([
				'=IS_REAL_USER' => 'Y'
			]);
			$convertedUserCount = OptionUserTable::getCount();

			$unconvertedUserCount = $userCount - $convertedUserCount;

			if ($unconvertedUserCount < 1)
			{
				if (empty($unconvertedUsers))
				{
					Option::delete(self::$moduleId, ['name' => 'unconverted_settings_users']);
				}

				Option::set(self::$moduleId, 'migration_to_new_settings', 'Y');
				Option::delete(self::$moduleId, ['name' => self::OPTION_NAME]);

				return false;
			}

			$params = [
				'lastId' => 0,
				'number' => 0,
				'defaultGroup' => $defaultGroupId,
				'includeIntranet' => $isIntranetIncluded,
				'count' => $unconvertedUserCount
			];
		}

		$query =
			UserTable::query()
				->addSelect('ID')
				->registerRuntimeField(
					'OPTION_USER',
					new Reference(
						'OPTION_USER',
						OptionUserTable::class,
						Join::on('this.ID', '=', 'ref.USER_ID'),
						['join_type' => Join::TYPE_LEFT]
					)
				)
				->where('IS_REAL_USER', 'Y')
				->where('OPTION_USER.USER_ID', null)
				->where('ID', '>', $params['lastId'])
				->setOrder(['ID' => 'ASC'])
				->setLimit(self::ITERATION_LIMIT)
		;

		$userIds = [];
		foreach ($query->exec() as $row)
		{
			$userIds[] = (int)$row['ID'];
		}

		if (empty($userIds))
		{
			if (empty($unconvertedUsers))
			{
				Option::delete(self::$moduleId, ['name' => 'unconverted_settings_users']);
			}

			Option::set(self::$moduleId, 'migration_to_new_settings', 'Y');
			Option::delete(self::$moduleId, ['name' => 'last_converted_user']);
			Option::delete(self::$moduleId, ['name' => self::OPTION_NAME]);

			return false;
		}

		$lastKeyId = array_key_last($userIds);
		$params['lastId']  = $userIds[$lastKeyId];

		foreach ($userIds as $userId)
		{
			try
			{
				$groupId = $this->isUserGroupExist($userId);
				if ($groupId)
				{
					$this->bindExistingGroupToUser($userId, $groupId, $params['defaultGroup']);

					continue;
				}
				$notifySettings = \CUserOptions::GetOption('im', 'notify', [], $userId);
				$generalSettings = \CUserOptions::GetOption('im', 'settings', [], $userId);

				if (empty($notifySettings) && empty($generalSettings))
				{
					OptionUserTable::add([
						'USER_ID' => $userId,
						'NOTIFY_GROUP_ID' => $params['defaultGroup'],
						'GENERAL_GROUP_ID' => $params['defaultGroup']
					]);
				}
				else
				{
					$this->createPersonalPreset($userId, $notifySettings, $generalSettings, $params['defaultGroup']);
				}
				$params['lastConvertedUser'] = $userId;
			}
			catch (\Exception $e)
			{
				$unconvertedUsers[] = $userId;
			}
			$params['number']++;
		}

		$option['count'] = $params['count'];
		$option['progress'] = ($params['number'] * 100) / (int)$params['count'];
		$option['steps'] = $params['number'];

		Option::set(self::$moduleId, 'last_converted_user', $params['lastConvertedUser']);
		Option::set(self::$moduleId, 'unconverted_settings_users', serialize($unconvertedUsers));
		Option::set(self::$moduleId, self::OPTION_NAME, serialize($params));

		return true;

	}

	private function convertNotifySettings(array $oldUserSettings): array
	{
		if (empty(self::$notifyDefaultSettings))
		{
			self::$notifyDefaultSettings = Notification::getSimpleNotifySettings(General::getDefaultSettings());
		}

		$newFormatSettings = [];
		foreach ($oldUserSettings as $name => $value)
		{
			[$type, $module, $event] = explode('|', $name, 3);

			switch ($type)
			{
				case 'site':
					$type = 1;
					break;

				case 'email':
					$type = 2;
					break;

				case 'xmpp':
					$type = 3;
					break;

				case 'push':
					$type = 4;
					break;
			}
			$newName = implode('|', ['no', $module, $event, $type]);

			$newFormatSettings[] = [
				'NAME' => $newName,
				'VALUE' => $value ? 'Y' : 'N'
			];
		}

		$newSettings = \Bitrix\Im\Configuration\Notification::decodeSettings($newFormatSettings);
		return array_replace_recursive(self::$notifyDefaultSettings, $newSettings);

	}

	private function convertGeneralSettings(array $oldUserSettings): array
	{
		if (empty(self::$generalDefaultSettings))
		{
			self::$generalDefaultSettings = General::getDefaultSettings();
		}

		return array_replace_recursive(self::$generalDefaultSettings, $oldUserSettings);
	}

	private function createDefaultPreset($includeIntranet): int
	{
		$defaultGroupId =
			OptionGroupTable::add([
				'NAME' => Configuration::DEFAULT_PRESET_NAME,
				'SORT' => 0,
				'CREATE_BY_ID' => 0,
			])
				->getId()
		;
		$generalDefaultSettings = General::getDefaultSettings();
		General::setSettings($defaultGroupId, $generalDefaultSettings);

		$notifySettings = Notification::getSimpleNotifySettings($generalDefaultSettings);
		Notification::setSettings($defaultGroupId, $notifySettings);


		if ($includeIntranet)
		{
			$topDepartmentId = Department::getTopDepartmentId();
			OptionAccessTable::add([
				'GROUP_ID' => $defaultGroupId,
				'ACCESS_CODE' => $topDepartmentId ? 'DR' . $topDepartmentId : 'AU'
			]);
		}

		return (int)$defaultGroupId;
	}

	private function createPersonalPreset($userId, $notifySettings, $generalSettings, $defaultGroupId): void
	{
		$userGroupId =
			OptionGroupTable::add([
				'USER_ID' => $userId,
				'SORT' => Configuration::USER_PRESET_SORT,
				'CREATE_BY_ID' => 0
			])
				->getId()
		;

		$isSettingsChanged = false;

		try
		{
			if (!empty($generalSettings))
			{
				$generalSettings = $this->convertGeneralSettings($generalSettings);
				$row =
					StatusTable::query()
						->addSelect('STATUS')
						->where('USER_ID', $userId)
						->fetch()
				;
				if ($row)
				{
					$generalSettings['status'] = $row['STATUS'];
				}

				General::setSettings($userGroupId, $generalSettings);

				if ($generalSettings['notifyScheme'] === 'simple' || empty($notifySettings))
				{
					$notifySettings = Notification::getSimpleNotifySettings($generalSettings);
				}
				else
				{
					$notifySettings = $this->convertNotifySettings($notifySettings);
				}

				Notification::setSettings($userGroupId, $notifySettings);
				$isSettingsChanged = true;
			}
		}
		catch (\Exception $exception) {}

		OptionUserTable::add([
			'USER_ID' => $userId,
			'NOTIFY_GROUP_ID' => $isSettingsChanged ? $userGroupId : $defaultGroupId,
			'GENERAL_GROUP_ID' => $isSettingsChanged ? $userGroupId : $defaultGroupId
		]);

		OptionAccessTable::add([
			'GROUP_ID' => $userGroupId,
			'ACCESS_CODE' => 'U' . $userId
		]);
	}

	private function getDefaultGroupId()
	{
		$defaultGroupId =
			OptionGroupTable::query()
				->addSelect('ID')
				->where('NAME', Configuration::DEFAULT_PRESET_NAME)
				->fetch();

		return $defaultGroupId ? $defaultGroupId['ID'] : false;
	}

	private function updateDefaultAccessCode($defaultGroupId): void
	{
		$topDepartmentId = Department::getTopDepartmentId();
		$accessCode = $topDepartmentId ? 'DR' . $topDepartmentId : 'AU';

		OptionAccessTable::update($defaultGroupId, [
			'ACCESS_CODE' => $accessCode
		]);
	}

	private function isUserGroupExist($userId)
	{
		$query =
			OptionGroupTable::query()
				->addSelect('ID')
				->where('USER_ID', $userId);

		$row = $query->fetch();
		if (!$row)
		{
			return false;
		}

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

	private function bindExistingGroupToUser($userId, $groupId, $defaultGroupId): void
	{
		$notifyCount = OptionStateTable::getCount([
			'=GROUP_ID' => $groupId,
			'%=NAME' => 'no%'
		]);

		$generalCount = OptionStateTable::getCount([
			'=GROUP_ID' => $groupId,
			'%=NAME' => 'se%'
		]);

		$notifyGroupId = $notifyCount > 0 ? $groupId : $defaultGroupId;
		$generalGroupId = $generalCount > 0 ? $groupId : $defaultGroupId;

		if ($notifyGroupId === $groupId && $generalGroupId === $groupId)
		{
			$insertFields = [
				'USER_ID' => $userId,
				'GENERAL_GROUP_ID' => $generalGroupId,
				'NOTIFY_GROUP_ID' => $notifyGroupId
			];
			$updateFields = [
				'GENERAL_GROUP_ID' => $generalGroupId,
				'NOTIFY_GROUP_ID' => $notifyGroupId
			];

			OptionUserTable::merge($insertFields, $updateFields);

			return;
		}

		$generalSettings = \CUserOptions::GetOption('im', 'settings', [], $userId);

		if ($generalGroupId === $defaultGroupId && !empty($generalSettings))
		{
			$generalGroupId = $groupId;
			$generalSettings = $this->convertGeneralSettings($generalSettings);

			General::setSettings($generalGroupId, $generalSettings);
		}

		if ($notifyGroupId === $defaultGroupId)
		{
			$notifySettings = \CUserOptions::GetOption('im', 'notify', [], $userId);

			if ($generalSettings['notifyScheme'] === 'simple')
			{
				$generalSettings = $this->convertGeneralSettings($generalSettings);
				$notifySettings = Notification::getSimpleNotifySettings($generalSettings);
			}

			if (!empty($notifySettings))
			{
				$notifyGroupId = $groupId;
				$notifySettings = $this->convertNotifySettings($notifySettings);
				Notification::setSettings($notifyGroupId, $notifySettings);
			}
		}

		$insertFields = [
			'USER_ID' => $userId,
			'GENERAL_GROUP_ID' => $generalGroupId,
			'NOTIFY_GROUP_ID' => $notifyGroupId
		];
		$updateFields = [
			'GENERAL_GROUP_ID' => $generalGroupId,
			'NOTIFY_GROUP_ID' => $notifyGroupId
		];

		OptionUserTable::merge($insertFields, $updateFields);
	}

}

Youez - 2016 - github.com/yon3zu
LinuXploit