• Модуль: main
  • Путь к файлу: ~/bitrix/modules/main/lib/orm/data/datamanager.php
  • Класс: BitrixMainORMDataDataManager
  • Вызов: DataManager::addMulti
static function addMulti($rows, $ignoreEvents = false)
{
	global $USER_FIELD_MANAGER;

	$rows = array_values($rows);
	$forceSeparateQueries = false;

	if (!$ignoreEvents && count($rows) > 1 && strlen(static::getEntity()->getAutoIncrement()))
	{
		$forceSeparateQueries = true;

		// change to warning
		trigger_error(
			'Multi-insert doesn't work with events as far as we can not get last inserted IDs that we need for the events. '.
			'Insert query was forced to multiple separate queries.',
			E_USER_NOTICE
		);
	}

	// prepare objects
	$objects = [];

	foreach ($rows as $k => &$row)
	{
		$objects[$k] = static::convertArrayToObject($row, true);
	}

	$entity = static::getEntity();
	$result = new AddResult();

	try
	{
		// call onBeforeEvent
		if (!$ignoreEvents)
		{
			foreach ($objects as $k => $object)
			{
				static::callOnBeforeAddEvent($object, $rows[$k], $result);
			}
		}

		// collect array data
		$allFields = [];
		$allUfData = [];

		foreach ($objects as $k => $object)
		{
			// actualize old-style fields array from object
			$allFields[$k] = $object->collectValues(Values::CURRENT, FieldTypeMask::SCALAR);

			// uf values
			$allUfData[$k] = $object->collectValues(Values::CURRENT, FieldTypeMask::USERTYPE);
		}

		// check data and uf
		foreach ($objects as $k => $object)
		{
			$fields = $allFields[$k];
			$ufdata = $allUfData[$k];

			// check data
			static::checkFields($result, null, $fields);

			// check uf data
			if (!empty($ufdata))
			{
				static::checkUfFields($object, $ufdata, $result);
			}

			// check if there is still some data
			if (empty($fields) && empty($ufdata))
			{
				$result->addError(new EntityError("There is no data to add."));
			}
		}

		// return if any error in any row
		if (!$result->isSuccess(true))
		{
			return $result;
		}

		//event on adding
		if (!$ignoreEvents)
		{
			foreach ($objects as $k => $object)
			{
				$fields = $allFields[$k];
				$ufdata = $allUfData[$k];

				self::callOnAddEvent($object, $fields, $ufdata);
			}
		}

		// prepare sql
		$allSqlData = [];

		foreach ($allFields as $k => $fields)
		{
			// use save modifiers
			$fieldsToDb = $fields;

			foreach ($fieldsToDb as $fieldName => $value)
			{
				$field = $entity->getField($fieldName);
				$fieldsToDb[$fieldName] = $field->modifyValueBeforeSave($value, $fields);
			}

			$dataReplacedColumn = static::replaceFieldName($fieldsToDb);

			$allSqlData[$k] = $dataReplacedColumn;
		}

		// save data
		$connection = $entity->getConnection();

		$tableName = $entity->getDBTableName();
		$identity = $entity->getAutoIncrement();
		$ids = [];

		// multi insert on db level
		if ($forceSeparateQueries)
		{
			foreach ($allSqlData as $k => $sqlData)
			{
				// remember all ids
				$ids[$k] = $connection->add($tableName, $sqlData, $identity);
			}
		}
		else
		{
			$id = $connection->addMulti($tableName, $allSqlData, $identity);
		}

		if (count($allSqlData) > 1)
		{
			// id doesn't make sense when multiple inserts
			$id = null;
		}
		else
		{
			$object = $objects[0];
			$fields = $allFields[0];

			// build standard primary
			$primary = null;

			if (!empty($id))
			{
				if($entity->getAutoIncrement() <> '')
				{
					$primary = array($entity->getAutoIncrement() => $id);
					static::normalizePrimary($primary);
				}
				else
				{
					// for those who did not set 'autocomplete' flag but want to get id from result
					$primary = array('ID' => $id);
				}
			}
			else
			{
				static::normalizePrimary($primary, $fields);
			}

			// fill result
			$result->setPrimary($primary);
			$result->setData($fields);
			$result->setObject($object);
		}

		// save uf data
		foreach ($allUfData as $k => $ufdata)
		{
			if (!empty($ufdata))
			{
				$ufUserId = false;

				if ($objects[$k]->authContext)
				{
					$ufUserId = $objects[$k]->authContext->getUserId();
				}

				$USER_FIELD_MANAGER->update($entity->getUfId(), end($primary), $ufdata, $ufUserId);
			}
		}

		static::cleanCache();

		// after event
		if (!$ignoreEvents)
		{
			foreach ($objects as $k => $object)
			{
				$fields = $allFields[$k] + $allUfData[$k];
				$id = $forceSeparateQueries ? $ids[$k] : null;

				static::callOnAfterAddEvent($object, $fields, $id);
			}
		}
	}
	catch (Exception $e)
	{
		// check result to avoid warning
		$result->isSuccess();

		throw $e;
	}

	return $result;
}