• Модуль: webdav
  • Путь к файлу: ~/bitrix/modules/webdav/classes/file.php
  • Класс: CWebDavFile
  • Вызов: CWebDavFile::COPY
function COPY(&$options, $drop = false)
{
	$io = self::GetIo();
	$options["dest_url"] = $this->MetaNamesReverse(explode("/", $options["dest_url"]));
	$options["dest_url"] = $io->CombinePath(static::_udecode($options["dest_url"]));

	if (!$this->CheckRights("COPY", true, $options["dest_url"])):
		$this->ThrowAccessDenied();
		return "403 Forbidden";
	elseif ($_SERVER['REQUEST_METHOD'] == "MOVE" && !empty($_SERVER["CONTENT_LENGTH"])):
		return "415 Unsupported media type";
	elseif ($options["path"] == $options["dest_url"]):
//			 $GLOBALS["APPLICATION"]->ThrowException(GetMessage("WD_FILE_ERROR2"), "EMPTY_DESTINATION_URL");
		return "204 No Content";
	elseif (empty($options["dest_url"])):
		$GLOBALS["APPLICATION"]->ThrowException(GetMessage("WD_FILE_ERROR2"), "EMPTY_DESTINATION_URL");
		return "502 Bad gateway";
	endif;
	$arDataFrom = array();
	$arDataTo = array();

	$from_parent_id = 0;
	$to_parent_id = 0;

	$from_ID = 0; $from_basename = "";
	$to_ID = 0; $to_basename = "";

	$is_dir = false;

	////////////// CHECK FROM
	$this->IsDir($options);
	$arFrom = $this->arParams;
	if ($this->arParams["is_dir"] === true):
		$from_ID = $this->arParams["item_id"];
		$is_dir = true;
	elseif ($this->arParams["is_file"] === true):
		$from_ID = $this->arParams["item_id"];
	else:
		$GLOBALS["APPLICATION"]->ThrowException(GetMessage("WD_FILE_ERROR3"), "DESTINATION_FILE_OR_FOLDER_IS_NOT_FOUND");
		return "404 Not Found";
	endif;

	$from_basename = $this->arParams["basename"];
	$from_parent_id = $this->arParams["parent_id"];

	if ($_SERVER['REQUEST_METHOD'] == "MOVE" && $is_dir && ($options["depth"] != "infinity")):
		return "400 Bad request";
	endif;

	////////////// CHECK TO

	$this->IsDir(array("path" => $options["dest_url"]), $this->replace_symbols);
	$options["dest_url"] = $this->_udecode($options["dest_url"]);
	$arTo = $this->arParams;
	if ($this->arParams["is_dir"] === true || $this->arParams["is_file"] === true):
		$to_ID = $this->arParams["item_id"];
	endif;

	if ($from_ID == $options["dest_url"]):
		return "204 No Content";
	elseif ($to_ID && $options['rename']):
		$nameSuffix = 1;
		do
		{
			$tmpName = $options["dest_url"]." (". $nameSuffix++ .")";
			$this->IsDir(array("path" => $tmpName), $this->replace_symbols);
			$arTo = $this->arParams;
		} while ($this->arParams["is_dir"] === true || $this->arParams["is_file"] === true);
		$options['dest_url'] = $tmpName;
		$to_ID = 0;
	elseif ($to_ID && !$options["overwrite"]):
		$GLOBALS["APPLICATION"]->ThrowException(GetMessage("WD_FILE_ERROR4"), "FILE_OR_FOLDER_ALREADY_EXISTS");
		return '412 Precondition failed';
	elseif ($is_dir && $this->arParams["is_file"]):
		$GLOBALS["APPLICATION"]->ThrowException(str_replace("#FOLDER#", $this->arParams["item_id"], GetMessage("WD_FILE_ERROR5")), "FOLDER_IS_EXISTS");
		return "400 bad Request";
	elseif ($arFrom['is_file'] && $arTo["is_dir"]):
		$GLOBALS["APPLICATION"]->ThrowException(str_replace("#FOLDER#", $this->arParams["item_id"], GetMessage("WD_FILE_ERROR5")), "FOLDER_IS_EXISTS");
		return "400 bad Request";
	endif;

	if (rtrim($arTo['parent_id'], '/') == $this->GetMetaID('TRASH'))
	{
		$arCheckTrashElement = $this->_get_props($arFrom["item_id"]);
		if ( ! isset($arCheckTrashElement["UNDELETEBX:"]))
		{
			$this->ThrowAccessDenied();
			$GLOBALS["APPLICATION"]->ThrowException(GetMessage("WD_ACCESS_DENIED"), "BAD_NAME");
			return "403 Forbidden";
		}
	}

	$__from = preg_replace("//+/is", "/", mb_strtolower($from_ID)."/");
	$__to = preg_replace("//+/is", "/", mb_strtolower(mb_substr($options["dest_url"], 0, mb_strlen($from_ID) + 1)."/"));
	if ($is_dir && $__from == $__to):
		$GLOBALS["APPLICATION"]->ThrowException(GetMessage("WD_FILE_ERROR100"), "SECTION_IS_NOT_UPDATED");
		return "400 Bad Request";
	endif;

	$to_parent_id = $this->arParams["parent_id"];
	$to_basename = $this->arParams["basename"];

	/*$from_url = $io->CombinePath($this->real_path_full, $from_ID);
	$to_url = $io->CombinePath($this->real_path_full, $options["dest_url"]);*/

	$from_url = CWebDavBase::CleanRelativePathString($from_ID, $this->real_path_full);
	$to_url = CWebDavBase::CleanRelativePathString($options["dest_url"], $this->real_path_full);
	if($from_url === false || $to_url === false)
	{
		return "400 Bad Request";
	}

	if (!$is_dir)
	{
		if ($to_ID && $options["overwrite"])
			$this->DELETE(array("path" => $options["dest_url"]));

		if (!$io->Copy($from_url, $to_url))
		{
			$GLOBALS["APPLICATION"]->ThrowException(str_replace("#FILE#", $this->arParams["item_id"], GetMessage("WD_FILE_ERROR6")), "FILE_IS_NOT_COPIED");
			return "500 Internal server error";
		}
		else
		{
			$this->_copy_props($from_ID, $options["dest_url"], $options["overwrite"]);
			$file = $to_url;
			$oFile = $io->GetFile($file);
			$path = str_replace(array($_SERVER['DOCUMENT_ROOT'], "///", "//"), "/", $file);

			if(CModule::IncludeModule("search"))
			{
				if (rtrim($arTo['parent_id'], '/') == $this->GetMetaID('TRASH'))
				{
					CSearch::DeleteIndex('main', SITE_ID.'|'.$path);
				}
				else
				{
					$this->Reindex($file);
				}
			}

			if (COption::GetOptionInt("main", "disk_space") > 0)
			{
				CDiskQuota::updateDiskQuota("file", $oFile->GetFileSize(), "add");
			}
		}
	}
	else
	{
		$params = $this->GetFilesAndFolders($from_ID);
		if (empty($params))
		{
			$GLOBALS["APPLICATION"]->ThrowException(GetMessage("WD_FILE_ERROR3"), "DESTINATION_FILE_OR_FOLDER_IS_NOT_EXISTS");
			return "500 Internal Server Error";
		}

		sort($params, SORT_STRING);

		foreach ($params as $file)
		{
			$file = CWebDavBase::CleanRelativePathString($file);
			if($file === false)
			{
				return "409 Conflict";
			}
			$bDir = $io->DirectoryExists($file);
			if ($bDir)
			{
				$file = $this->_slashify($file);
			}

			$destfile = str_replace($from_url, $to_url, $file);

			if ($bDir)
			{
				if (
					! $io->DirectoryExists($destfile)
					&& ! $io->CreateDirectory($destfile)
				)
				{
					$GLOBALS["APPLICATION"]->ThrowException(str_replace("#FOLDER#", str_replace($this->real_path_full, "", $destfile), GetMessage("WD_FILE_ERROR7")), "FOLDER_IS_NOT_CREATED");
					return "409 Conflict";
				}
				else
				{
					$this->_copy_props(str_replace(array($this->real_path_full, "///", "//"), "/", $file), str_replace(array($this->real_path_full, "///", "//"), "/", $destfile), $drop);
				}
			}
			else
			{
				if ($io->FileExists($destfile))
				{
					if (!$options["overwrite"])
					{
						$GLOBALS["APPLICATION"]->ThrowException(str_replace("#FILE#", str_replace($this->real_path_full, "", $destfile), GetMessage("WD_FILE_ERROR8")), "FILE_ALREADY_EXISTS");
						return "409 Conflict";
					}
					$this->DELETE(array("path" => str_replace(array($this->real_path_full, "///", "//"), "/", $destfile)));
				}
				if (!$io->Copy($file, $destfile))
				{
					$GLOBALS["APPLICATION"]->ThrowException(str_replace("#FILE#", str_replace($this->real_path_full, "", $destfile), GetMessage("WD_FILE_ERROR6")), "FILE_IS_NOT_COPIED");
					return "409 Conflict";
				}
				else
				{

					//$this->_copy_props(str_replace(array($this->real_path_full, "///", "//"), "/", $file), str_replace(array($this->real_path_full, "///", "//"), "/", $destfile), $drop);
					$this->_copy_props(str_replace($this->real_path_full, "/", $file), str_replace($this->real_path_full, "/", $destfile), $drop);
					$file = $destfile;

					$this->Reindex($file);
					if (COption::GetOptionInt("main", "disk_space") > 0)
					{
						$oFile = $io->GetFile($file);
						CDiskQuota::updateDiskQuota("file", $oFile->GetFileSize(), "add");
					}
				}
			}
		}
	}

	clearstatcache();

	if ($drop)
	{
		$result = $this->DELETE(array("path" => $from_ID, "force" => true));
		if (intval($result) != 204)
			return $result;
	}
	return (!$to_ID ? "201 Created" : "204 No Content");
}