- Модуль: main
- Путь к файлу: ~/bitrix/modules/main/lib/orm/data/datamanager.php
- Класс: BitrixMainORMDataDataManager
- Вызов: DataManager::updateMulti
static function updateMulti($primaries, $data, $ignoreEvents = false)
{
$entity = static::getEntity();
$primaries = array_values($primaries);
/** @var EntityObject[] $objects */
$objects = [];
foreach ($primaries as &$primary)
{
static::normalizePrimary($primary, $data);
static::validatePrimary($primary);
/** @var EntityObject $object */
$object = $entity->wakeUpObject($primary);
foreach ($data as $k => $v)
{
$object->set($k, $v);
}
$objects[] = $object;
}
$result = new UpdateResult;
try
{
// before event
if (!$ignoreEvents)
{
foreach ($objects as $object)
{
static::callOnBeforeUpdateEvent($object, $data, $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, $object->primary, $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];
static::callOnUpdateEvent($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;
}
// check if rows data are equal
$areEqual = true;
$dataSample = $allSqlData[0];
asort($dataSample);
if (!empty($allSqlData[0]))
{
foreach ($allSqlData as $data)
{
asort($data);
if ($data !== $dataSample)
{
$areEqual = false;
break;
}
}
// save data
$connection = $entity->getConnection();
$helper = $connection->getSqlHelper();
$tableName = $entity->getDBTableName();
// save data
if ($areEqual)
{
// one query
$update = $helper->prepareUpdate($tableName, $dataSample);
$where = [];
$isSinglePrimary = (count($entity->getPrimaryArray()) == 1);
foreach ($allSqlData as $k => $data)
{
$replacedPrimary = static::replaceFieldName($objects[$k]->primary);
if ($isSinglePrimary)
{
// for single primary IN is better
$primaryName = key($replacedPrimary);
$primaryValue = current($replacedPrimary);
$tableField = $entity->getConnection()->getTableField($tableName, $primaryName);
$where[] = $helper->convertToDb($primaryValue, $tableField);
}
else
{
$id = [];
foreach ($replacedPrimary as $primaryName => $primaryValue)
{
$id[] = $helper->prepareAssignment($tableName, $primaryName, $primaryValue);
}
$where[] = implode(' AND ', $id);
}
}
if ($isSinglePrimary)
{
$where = $helper->quote($entity->getPrimary()).' IN ('.join(', ', $where).')';
}
else
{
$where = '('.join(') OR (', $where).')';
}
$sql = "UPDATE ".$helper->quote($tableName)." SET ".$update[0]." WHERE ".$where;
$connection->queryExecute($sql, $update[1]);
$result->setAffectedRowsCount($connection);
}
else
{
// query for each row
foreach ($allSqlData as $k => $dataReplacedColumn)
{
$update = $helper->prepareUpdate($tableName, $dataReplacedColumn);
$replacedPrimary = static::replaceFieldName($objects[$k]->primary);
$id = [];
foreach ($replacedPrimary as $primaryName => $primaryValue)
{
$id[] = $helper->prepareAssignment($tableName, $primaryName, $primaryValue);
}
$where = implode(' AND ', $id);
$sql = "UPDATE ".$helper->quote($tableName)." SET ".$update[0]." WHERE ".$where;
$connection->queryExecute($sql, $update[1]);
$result->setAffectedRowsCount($connection);
}
}
}
// doesn't make sense for multiple rows
$result->setData($dataSample);
if (count($allSqlData) == 1)
{
$result->setPrimary($objects[0]->primary);
$result->setObject($objects[0]);
}
// save uf data
foreach ($allUfData as $ufdata)
{
if (!empty($ufdata))
{
global $USER_FIELD_MANAGER;
$USER_FIELD_MANAGER->update($entity->getUfId(), end($primary), $ufdata);
}
}
static::cleanCache();
// event after update
if (!$ignoreEvents)
{
foreach ($objects as $k => $object)
{
$fields = $allFields[$k] + $allUfData[$k];
static::callOnAfterUpdateEvent($object, $fields);
}
}
}
catch (Exception $e)
{
// check result to avoid warning
$result->isSuccess();
throw $e;
}
return $result;
}