• Модуль: main
  • Путь к файлу: ~/bitrix/modules/main/classes/general/zip.php
  • Класс: CZip
  • Вызов: CZip::_addFile
private function _addFile($filename, &$arHeader, $addDir, $removeDir, $removeAllDir = false, $arParams = [])
{
	$res = 1;

	if ($filename == "")
	{
		$this->_errorLog("ERR_PARAM_LIST", GetMessage("MAIN_ZIP_ERR_PARAM_LIST"));
		return $this->arErrors;
	}

	//saved filename
	$storedFilename = $filename;

	//remove the path
	if ($removeAllDir)
	{
		$storedFilename = basename($filename);
	}
	else
	{
		if ($removeDir != "")
		{
			if (mb_substr($removeDir, -1) != '/')
			{
				$removeDir .= "/";
			}

			if ((mb_substr($filename, 0, 2) == "./") || (mb_substr($removeDir, 0, 2) == "./"))
			{
				if ((mb_substr($filename, 0, 2) == "./") && (mb_substr($removeDir, 0, 2) != "./"))
				{
					$removeDir = "./" . $removeDir;
				}
				if ((mb_substr($filename, 0, 2) != "./") && (mb_substr($removeDir, 0, 2) == "./"))
				{
					$removeDir = mb_substr($removeDir, 2);
				}
			}

			$incl = $this->_containsPath($removeDir, $filename);

			if ($incl > 0)
			{
				if ($incl == 2)
				{
					$storedFilename = "";
				}
				else
				{
					$storedFilename = mb_substr($filename, mb_strlen($removeDir));
				}
			}
		}
	}

	if ($addDir != "")
	{
		if (mb_substr($addDir, -1) == "/")
		{
			$storedFilename = $addDir . $storedFilename;
		}
		else
		{
			$storedFilename = $addDir . "/" . $storedFilename;
		}
	}

	//make the filename
	$storedFilename = $this->_reducePath($storedFilename);

	//save file properties
	clearstatcache();
	$arHeader['comment'] = '';
	$arHeader['comment_len'] = 0;
	$arHeader['compressed_size'] = 0;
	$arHeader['compression'] = 0;
	$arHeader['crc'] = 0;
	$arHeader['disk'] = 0;
	$arHeader['external'] = (is_file($filename) ? 0xFE49FFE0 : 0x41FF0010);
	$arHeader['extra'] = '';
	$arHeader['extra_len'] = 0;
	$arHeader['filename'] = BitrixMainTextEncoding::convertEncoding($filename, $this->fileSystemEncoding, "cp866");
	$arHeader['filename_len'] = strlen(BitrixMainTextEncoding::convertEncoding($filename, $this->fileSystemEncoding, "cp866"));
	$arHeader['flag'] = 0;
	$arHeader['index'] = -1;
	$arHeader['internal'] = 0;
	$arHeader['mtime'] = filemtime($filename);
	$arHeader['offset'] = 0;
	$arHeader['size'] = filesize($filename);
	$arHeader['status'] = 'ok';
	$arHeader['stored_filename'] = BitrixMainTextEncoding::convertEncoding($storedFilename, $this->fileSystemEncoding, "cp866");
	$arHeader['version'] = 20;
	$arHeader['version_extracted'] = 10;

	//pre-add callback
	if ((isset($arParams['callback_pre_add'])) && ($arParams['callback_pre_add'] != ''))
	{
		//generate local information
		$arLocalHeader = [];
		$this->_convertHeader2FileInfo($arHeader, $arLocalHeader);

		//callback call
		eval('$res = ' . $arParams['callback_pre_add'] . '('callback_pre_add', $arLocalHeader);');
		//if res == 0 change the file status
		if ($res == 0)
		{
			$arHeader['status'] = "skipped";
			$res = 1;
		}

		//update the info, only some fields can be modified
		if ($arHeader['stored_filename'] != $arLocalHeader['stored_filename'])
		{
			$arHeader['stored_filename'] = $this->_reducePath($arLocalHeader['stored_filename']);
		}
	}

	//if stored filename is empty - filter
	if ($arHeader['stored_filename'] == "")
	{
		$arHeader['status'] = "filtered";
	}

	//check path length
	if (mb_strlen($arHeader['stored_filename']) > 0xFF)
	{
		$arHeader['status'] = 'filename_too_long';
	}

	//if no error
	if ($arHeader['status'] == 'ok')
	{
		if (is_file($filename))
		{
			//reading source
			if (($file = @fopen($filename, "rb")) == 0)
			{
				$this->_errorLog("ERR_READ", str_replace("#FILE_NAME#", removeDocRoot($filename), GetMessage("MAIN_ZIP_ERR_READ")));
				return $this->arErrors;
			}

			//reading the file content
			$content = $arHeader['size'] > 0 ? fread($file, $arHeader['size']) : '';
			//calculating crc
			$arHeader['crc'] = crc32($content);
			//compress the file
			$compressedContent = empty($arParams['no_compression']) ? gzdeflate($content) : $content;

			//set header params
			$arHeader['compressed_size'] = strlen($compressedContent);
			$arHeader['compression'] = 8;

			//generate header
			if (($res = $this->_writeFileHeader($arHeader)) != 1)
			{
				@fclose($file);
				return $res;
			}

			//writing the compressed content
			$binary_data = pack('a' . $arHeader['compressed_size'], $compressedContent);
			@fwrite($this->zipfile, $binary_data, $arHeader['compressed_size']);

			@fclose($file);
		}
		//if directory
		else
		{
			//set file properties
			$arHeader['filename'] .= '/';
			$arHeader['filename_len']++;
			$arHeader['size'] = 0;
			//folder value. to be checked
			$arHeader['external'] = 0x41FF0010;

			//generate header
			if (($res = $this->_writeFileHeader($arHeader)) != 1)
			{
				return $res;
			}
		}
	}

	//pre-add callack
	if ((isset($arParams['callback_post_add'])) && ($arParams['callback_post_add'] != ''))
	{
		//make local info
		$arLocalHeader = [];
		$this->_convertHeader2FileInfo($arHeader, $arLocalHeader);

		//callback call
		eval('$res = ' . $arParams['callback_post_add'] . '('callback_post_add', $arLocalHeader);');

		if ($res == 0)
		{
			$res = 1;
		} //ignored
	}

	return $res;
}