function copy_commit($arFrom, $arTo, $options, $drop = false)
{
$result = true;
$actionWithSymlink = !empty($arFrom['is_symlink']) || !empty($arTo['is_symlink']);
$action = ($drop ? 'move' : 'copy');
if (!$this->CheckWebRights("", array('action' => $action, 'from' => $arFrom, 'to' => $arTo))) // warning: array param
return $this->ThrowAccessDenied(__LINE__);
$toIblockId = $this->IBLOCK_ID;
if(!empty($arTo['IBLOCK_ID']))
{
$toIblockId = $arTo['IBLOCK_ID'];
}
$fromIblockId = $this->IBLOCK_ID;
if(!empty($arFrom['IBLOCK_ID']))
{
$fromIblockId = $arFrom['IBLOCK_ID'];
}
$arFromSections = $this->GetSectionsTree(array("section_id" => $arFrom["ID"]));
$arToSections = $this->GetSectionsTree(array("section_id" => $arTo["ID"], 'not_check_permissions' => true));
$res = array();
foreach ($arToSections as $key => $val)
$res[$val["PATH"]] = $val;
$arToSections = $res;
$arSectionsToCopyElements[$arFrom["ID"]] = array("TO_ID" => $arTo["ID"], "NEED_CHECK_NAME" => true);
$result = true;
$bSectionsWasUpdated = false;
$res = reset($arFromSections);
$arParentId = array(intval($arTo["ID"]), $res["ID"]);
$iParentDeep = intval($res["DEPTH_LEVEL"]);
if (!empty($arFromSections))
{
$se = new CIBlockSection();
do
{
$res["DEPTH_LEVEL"] = intval($res["DEPTH_LEVEL"]);
while ($res["DEPTH_LEVEL"] <= $iParentDeep)
{
array_pop($arParentId);
$iParentDeep--;
}
if (!array_key_exists($res["PATH"], $arToSections))
{
if (!$actionWithSymlink && $drop === true) // Moving folders
{
$GLOBALS['DB']->StartTransaction();
$se_result = $se->Update($res["ID"], array("IBLOCK_SECTION_ID" => end($arParentId)));
if (!$se_result)
{
$GLOBALS['DB']->Rollback();
$result = $this->ThrowError("409 Conflict", "FOLDER_IS_NOT_MOVED", str_replace(
array("#FOLDER#", "#TEXT_ERROR#"),
array($res["PATH"], $se->LAST_ERROR), GetMessage("WD_FILE_ERROR103")), __LINE__);
break;
}
else
{
$GLOBALS['DB']->Commit();
}
$this->_onEvent( 'Move', $res["ID"], "FOLDER", array( 'TO' => end($arParentId)));
$bSectionsWasUpdated = true;
// Remove brunch elements as we move all the brunch
$deep = intval($res["DEPTH_LEVEL"]);
while ($res = next($arFromSections))
{
$res["DEPTH_LEVEL"] = intval($res["DEPTH_LEVEL"]);
if ($deep <= $res["DEPTH_LEVEL"])
{
prev($arFromSections);
break;
}
}
}
else // Copy folders
{
$se_result = $se->Add(array("IBLOCK_ID" => $toIblockId, "IBLOCK_SECTION_ID" => end($arParentId), "NAME" => $res["NAME"]));
if (!$se_result)
{
$result = $this->ThrowError("409 Conflict", "FOLDER_IS_NOT_MOVED", str_replace(
array("#FOLDER#", "#TEXT_ERROR#"),
array($res["PATH"], $se->LAST_ERROR), GetMessage("WD_FILE_ERROR104")), __LINE__);
break;
}
$this->_onEvent('Add', $se_result, 'FOLDER');
$bSectionsWasUpdated = true;
$arSectionsToCopyElements[$res["ID"]] = array("TO_ID" => $se_result, "NEED_CHECK_NAME" => false);
$arParentId[] = $se_result;
$iParentDeep++;
}
}
else
{
$arParentId[] = $arToSections[$res["PATH"]]["ID"];
$iParentDeep++;
if (!$options["overwrite"])
{
$result = $this->ThrowError("409 Conflict", "FOLDER_ALREADY_EXISTS", str_replace("#FOLDER#", $res["PATH"], GetMessage("WD_FILE_ERROR5")), __LINE__);
break;
}
else
{
$arSectionsToCopyElements[$res["ID"]] = array("TO_ID" => $arToSections[$res["PATH"]]["ID"], "NEED_CHECK_NAME" => true);
}
}
} while ($res = next($arFromSections));
if ($bSectionsWasUpdated)
{
$this->ClearCache("section");
}
}
if ($result === true)
{
$el = new CIBlockElement();
foreach ($arSectionsToCopyElements as $iFromSectionID => $arElement)
{
$arToElements = array();
if ($arElement["NEED_CHECK_NAME"] != false)
{
$db_res = CIBlockElement::GetList(
array("NAME" => "ASC"),
array("IBLOCK_ID" => $toIblockId, "SECTION_ID" => $arElement["TO_ID"], "SHOW_NEW" => "Y", "CHECK_PERMISSIONS" => "N"),
false,
false,
array("ID", "NAME"));
if ($db_res && $res = $db_res->Fetch())
{
do
{
$arToElements[mb_strtolower($res["NAME"])] = $res;
} while ($res = $db_res->Fetch());
}
}
$db_res = CIBlockElement::GetList(
array("NAME" => "ASC"),
array("IBLOCK_ID" => $fromIblockId, "SECTION_ID" => $iFromSectionID, "SHOW_NEW" => "Y"),
false,
false,
array("ID", "NAME", "IBLOCK_SECTION_ID", "PROPERTY_".$this->file_prop));
if ($db_res && $res = $db_res->Fetch())
{
do
{
$res["NAME"] = mb_strtolower($res["NAME"]);
if (array_key_exists($res["NAME"], $arToElements))
{
if (!$options["overwrite"])
{
$result = $this->ThrowError( "409 Conflict", "FILE_ALREADY_EXISTS", str_replace("#FILE#", $res["NAME"], GetMessage("WD_FILE_ERROR8")), __LINE__);
break;
}
else
{ // TODO: check permission to destroy elements
$tmp = $arToElements[$res["NAME"]];
$this->_onEvent('Delete', $tmp["ID"]);
$this->_ib_elm_delete($tmp["ID"]);
}
}
if (!$actionWithSymlink && $drop == true)
{
if ($this->workflow == 'bizproc' || $this->workflow == 'bizproc_limited')
{
$this->AddDocumentToHistory($res['ID'], $res['NAME']);
}
$el->Update(
$res["ID"],
array("IBLOCK_SECTION_ID" => $arElement["TO_ID"], "WF_COMMENTS" => GetMessage("WD_FILE_IS_MOVED")),
($this->workflow == 'workflow'));
$this->_onEvent( 'Move', $res["ID"], "FILE", array( 'TO' => $arElement["TO_ID"]));
if ($this->workflow == 'bizproc' || $this->workflow == 'bizproc_limited')
{
$db_res2 = CIBlockElement::GetList(array(), array("WF_PARENT_ELEMENT_ID" => $res["ID"], "SHOW_HISTORY" => "Y"), false, false, array("ID"));
if ($db_res2 && $res2 = $db_res2->Fetch())
{
do
{
$res = $el->Update($res2["ID"], array("IBLOCK_SECTION_ID" => $arElement["TO_ID"]), false, true, false, false);
} while ($res2 = $db_res2->Fetch());
}
}
}
else
{
if($actionWithSymlink)
{
//move and don't delete item
if(!self::_move_from_iblock_to_iblock($res["ID"], $toIblockId, $arElement["TO_ID"], false, true))
{
return '409 Conflict';
}
elseif($drop) //move action
{
//$this->DELETE(array("element_id" => $res["ID"]));
//delete section in method COPY
}
}
else
{
$arFile = CFile::GetFileArray($res["PROPERTY_".$this->file_prop."_VALUE"]);
$optionsPut = array(
'path' => $this->_udecode($this->_get_path($arElement["TO_ID"]))."/".$res["NAME"],
'content_length' => $arFile['FILE_SIZE'],
'content_type' => $arFile['CONTENT_TYPE']);
$stat = $this->PUT($optionsPut);
if ($stat === false)
{
return '403 Forbidden';
}
elseif (is_resource($stat) && get_resource_type($stat) == 'stream')
{
fclose($stat);
$arTmpFile = CFile::MakeFileArray($arFile['ID']); // since CopyDirFiles doesn't support clouds
if (!(is_array($arTmpFile) && is_set($arTmpFile, 'tmp_name')))
return '409 Conflict';
CopyDirFiles($arTmpFile['tmp_name'], $optionsPut["TMP_FILE"]);
clearstatcache();
$optionsPut['USER_FIELDS'] = $this->GetUfFields($res["ID"]);
if (!$this->put_commit($optionsPut))
{
return '409 Conflict';
}
}
}
}
} while ($res = $db_res->Fetch());
}
if ($result !== true)
{
break;
}
}
}
return $result;
}