- Модуль: 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;
}