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/main/lib/orm/data/addstrategy/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/main/lib/orm/data/addstrategy/merge.php
<?php

namespace Bitrix\Main\ORM\Data\AddStrategy;

use Bitrix\Main\NotSupportedException;
use Bitrix\Main\ORM\Data\AddStrategy\Contract\AddStrategy;
use Bitrix\Main\ORM\Data\AddStrategy\Internal\Helper;
use Bitrix\Main\ORM\Entity;
use Bitrix\Main\ORM\Fields\ScalarField;

final class Merge implements AddStrategy
{
	private readonly array $uniqueFieldNames;
	private readonly array $uniqueDbColumns;

	public function __construct(
		private readonly Entity $entity,
		?array $uniqueFieldNames = null,
	)
	{
		$uniqueFieldNames ??= $this->entity->getPrimaryArray();

		if (!Helper::isEntitySupportedByUniqueValidatingStrategies($this->entity, $uniqueFieldNames))
		{
			throw new NotSupportedException('Entity is not supported by the ' . self::class);
		}

		sort($uniqueFieldNames, SORT_STRING);
		$this->uniqueFieldNames = $uniqueFieldNames;

		$uniqueDbColumns = $this->replaceFieldNames($this->uniqueFieldNames);
		sort($uniqueDbColumns, SORT_STRING);
		$this->uniqueDbColumns = $uniqueDbColumns;
	}

	public function add(array $dbFields): AddedData
	{
		$updateDbFields = $this->getUpdateDbFields($dbFields, $this->uniqueDbColumns);

		$insertedId = $this->merge(
			$dbFields,
			$updateDbFields,
			$this->uniqueDbColumns,
		);

		$isDBChanged = $this->isDBChanged();

		if ($insertedId !== 0)
		{
			return new AddedData($insertedId, $isDBChanged);
		}
		else
		{
			return new AddedData(
				Helper::guessInsertedId($this->entity, $dbFields, $this->uniqueFieldNames),
				$isDBChanged,
			);
		}
	}

	public function addMulti(array $multiDbFields): AddedMultiData
	{
		foreach ($multiDbFields as &$dbFields)
		{
			// prepareMergeValues looks on key *order* in fields, not key *name*
			ksort($dbFields, SORT_STRING);
		}

		$firstDbFields = reset($multiDbFields);
		$updateDbColumns = array_keys(
			$this->getUpdateDbFields($firstDbFields, $this->uniqueDbColumns),
		);

		$connection = $this->entity->getConnection();

		// never force separate queries, since events are always ignored
		$sql = $connection->getSqlHelper()->prepareMergeValues(
			$this->entity->getDBTableName(),
			$this->uniqueDbColumns,
			$multiDbFields,
			$updateDbColumns,
		);

		$connection->queryExecute($sql);

		return new AddedMultiData($this->isDBChanged());
	}

	private function merge(array $insertFields, array $updateFields, array $uniqueFieldNames): int
	{
		$sqlHelper = $this->entity->getConnection()->getSqlHelper();

		$sql = $sqlHelper->prepareMerge(
			$this->entity->getDBTableName(),
			$uniqueFieldNames,
			$insertFields,
			$updateFields
		);

		return Helper::executeAndGetInsertedId($this->entity, current($sql));
	}

	private function replaceFieldNames(array $fieldNames): array
	{
		$result = [];
		foreach ($fieldNames as $fieldName)
		{
			$field = $this->entity->getField($fieldName);

			$result[] = $field instanceof ScalarField ? $field->getColumnName() : $fieldName;
		}

		return $result;
	}

	/**
	 * @param Array<string, mixed> $dbFields
	 *
	 * @return Array<string, mixed>
	 */
	private function getUpdateDbFields(array $dbFields, array $uniqueColumns): array
	{
		$update = [];
		foreach ($dbFields as $column => $value)
		{
			if (!in_array($column, $uniqueColumns, true))
			{
				$update[$column] = $value;
			}
		}

		return $update;
	}

	private function isDBChanged(): bool
	{
		// on mysql count will be 0 if no changes, 1 if inserted, 2 if a row was updated
		// pgsql will always return 1 on merge
		return $this->entity->getConnection()->getAffectedRowsCount() > 0;
	}
}

Youez - 2016 - github.com/yon3zu
LinuXploit