18 private $arErrors = [];
19 private $fileSystemEncoding;
24 private $compress =
true;
25 private $remove_path =
"";
26 private $add_path =
"";
27 private $replaceExistentFiles =
false;
28 private $checkPermissions =
true;
30 private $step_time = 30;
31 private $arPackedFiles = [];
32 private $arPackedFilesData = [];
37 $this->zipname = $this->_convertWinPath($pzipname,
false);
39 $this->fileSystemEncoding = $this->_getfileSystemEncoding();
48 public function Pack($arFileList, $startFile =
"")
51 $this->startFile = $this->io->GetPhysicalName($startFile);
52 $this->arPackedFiles = [];
53 $this->arHeaders = [];
54 $arCentralDirInfo = [];
55 $zipfile_tmp = $zipname_tmp =
'';
58 if ($startFile !=
"" && is_file($this->io->GetPhysicalName($this->zipname)))
60 $isNewArchive =
false;
65 if (!$this->_openFile(
"wb"))
72 if (!$this->_openFile(
"rb"))
78 if ((
$res = $this->_readEndCentralDir($arCentralDirInfo)) != 1)
84 @rewind($this->zipfile);
87 $zipname_tmp =
GetDirPath($this->zipname) . uniqid(
'ziparc') .
'.tmp';
88 if (($zipfile_tmp = @fopen($this->io->GetPhysicalName($zipname_tmp),
'wb')) == 0)
91 $this->_errorLog(
"ERR_READ_TMP", str_replace(
"#FILE_NAME#",
removeDocRoot($zipname_tmp),
GetMessage(
"MAIN_ZIP_ERR_READ_TMP")));
92 return $this->arErrors;
96 $size = $arCentralDirInfo[
'offset'];
100 $length = ($size < self::ReadBlockSize ? $size : self::ReadBlockSize);
101 $buffer = fread($this->zipfile, $length);
102 @fwrite($zipfile_tmp,
$buffer, $length);
108 $this->zipfile = $zipfile_tmp;
109 $zipfile_tmp = $tmp_id;
113 define(
"ZIP_START_TIME", microtime(
true));
114 $this->tempres =
null;
116 $arFileList = $this->_parseFileParams($arFileList);
118 $arConvertedFileList = [];
119 foreach ($arFileList as $fullpath)
121 $arConvertedFileList[] = $this->io->GetPhysicalName($fullpath);
125 if (is_array($arFileList) && !empty($arFileList))
127 $packRes = $this->_processFiles($arConvertedFileList, $this->add_path, $this->remove_path);
134 $offset = @ftell($this->zipfile);
137 for (
$i = 0,
$counter = 0;
$i <
sizeof($this->arPackedFiles);
$i++)
140 if ($this->arHeaders[
$i][
'status'] ==
'ok')
142 if ((
$res = $this->_writeCentralFileHeader($this->arHeaders[
$i])) != 1)
149 $this->_convertHeader2FileInfo($this->arHeaders[
$i], $this->arPackedFilesData[
$i]);
154 $size = @ftell($this->zipfile) - $offset;
156 if ((
$res = $this->_writeCentralHeader(
$counter, $size, $offset, $zip_comment)) != 1)
158 $this->arHeaders =
null;
165 $offset = @ftell($this->zipfile);
168 $size = $arCentralDirInfo[
'size'];
171 $length = ($size < self::ReadBlockSize ? $size : self::ReadBlockSize);
172 $buffer = @fread($zipfile_tmp, $length);
173 @fwrite($this->zipfile,
$buffer, $length);
181 if ($this->arHeaders[
$i][
'status'] ==
'ok')
183 if ((
$res = $this->_writeCentralFileHeader($this->arHeaders[
$i])) != 1)
185 fclose($zipfile_tmp);
187 @unlink($this->io->GetPhysicalName($zipname_tmp));
194 $this->_convertHeader2FileInfo($this->arHeaders[
$i], $this->arPackedFilesData[
$i]);
200 $size = @ftell($this->zipfile) - $offset;
203 if ((
$res = $this->_writeCentralHeader(
$counter + $arCentralDirInfo[
'entries'], $size, $offset, $zip_comment)) != 1)
206 $this->arHeaders =
null;
212 $this->zipfile = $zipfile_tmp;
213 $zipfile_tmp = $tmp_id;
216 @fclose($zipfile_tmp);
220 $this->_renameTmpFile($zipname_tmp, $this->zipname);
223 if ($isNewArchive && (
$res ===
false))
233 if ($packRes ===
'continue')
235 $this->startFile = $this->io->GetLogicalName(array_pop($this->arPackedFiles));
238 if ($packRes ===
false)
242 elseif ($packRes && $this->startFile ==
"")
246 elseif ($packRes && $this->startFile !=
"")
254 private function _haveTime()
256 return microtime(
true) - ZIP_START_TIME < $this->step_time;
259 private function _processFiles($arFileList, $addPath, $removePath)
261 $addPath = str_replace(
"\\",
"/", $addPath);
262 $removePath = str_replace(
"\\",
"/", $removePath);
266 $this->arErrors[] = [
"ERR_DFILE",
GetMessage(
"MAIN_ZIP_ERR_DFILE")];
270 if (!is_array($arFileList) || empty($arFileList))
277 if (!isset($this->tempres))
279 $this->tempres =
"started";
283 while ($j++ <
count($arFileList) && ($this->tempres ===
"started"))
294 $this->arErrors[] = [
"ERR_NO_FILE", str_replace(
"#FILE_NAME#",
$filename,
GetMessage(
"MAIN_ZIP_ERR_NO_FILE"))];
304 if ($this->startFile <>
'')
314 $this->startFile =
null;
320 if ($this->checkPermissions)
328 if ($this->_haveTime())
330 if (!$this->_addFile(
$filename, $arFileHeaders, $this->add_path, $this->remove_path))
333 $this->tempres =
false;
339 $this->arHeaders[] = $arFileHeaders;
344 $this->tempres =
'continue';
345 return $this->tempres;
353 $this->arErrors[] = [
"ERR_DIR_OPEN_FAIL", str_replace(
"#DIR_NAME#",
$filename,
GetMessage(
"MAIN_ZIP_ERR_DIR_OPEN_FAIL"))];
357 if ($this->checkPermissions)
369 $arFileList_tmp = [];
376 $arFileList_tmp[] =
$dir;
379 $this->_processFiles($arFileList_tmp, $addPath, $removePath);
383 unset($arFileList_tmp);
389 return $this->tempres;
398 return $this->startFile;
413 "add_path" => $this->add_path,
414 "remove_path" => $this->remove_path,
415 "extract_as_string" =>
false,
416 "remove_all_path" =>
false,
417 "callback_pre_extract" =>
"",
418 "callback_post_extract" =>
"",
421 "by_index" => array_key_exists(
"by_index", $rule) ? $rule[
'by_index'] :
"",
455 $this->compress =
$arOptions[
"COMPRESS"] ===
true;
460 $this->add_path = $this->io->GetPhysicalName(str_replace(
"\\",
"/", strval(
$arOptions[
"ADD_PATH"])));
463 if (array_key_exists(
"REMOVE_PATH",
$arOptions))
465 $this->remove_path = $this->io->GetPhysicalName(str_replace(
"\\",
"/", strval(
$arOptions[
"REMOVE_PATH"])));
468 if (array_key_exists(
"STEP_TIME",
$arOptions))
470 $this->step_time = floatval(
$arOptions[
"STEP_TIME"]);
473 if (array_key_exists(
"UNPACK_REPLACE",
$arOptions))
475 $this->replaceExistentFiles =
$arOptions[
"UNPACK_REPLACE"] ===
true;
478 if (array_key_exists(
"CHECK_PERMISSIONS",
$arOptions))
480 $this->checkPermissions =
$arOptions[
"CHECK_PERMISSIONS"] ===
true;
496 "COMPRESS" => $this->compress,
497 "ADD_PATH" => $this->add_path,
498 "REMOVE_PATH" => $this->remove_path,
499 "STEP_TIME" => $this->step_time,
500 "UNPACK_REPLACE" => $this->replaceExistentFiles,
501 "CHECK_PERMISSIONS" => $this->checkPermissions,
502 "RULE" => $this->rule,
514 return $this->arErrors;
525 $this->_errorReset();
533 [
'no_compression' =>
false,
536 'remove_all_path' =>
false]) != 1)
542 if (is_array($arFileList))
544 $res = $this->_createArchive($arFileList, $arResultList,
$arParams);
548 if (is_string($arFileList))
550 $arTmpList = explode(
",", $arFileList);
551 $res = $this->_createArchive($arTmpList, $arResultList,
$arParams);
555 $this->_errorLog(
"ERR_PARAM",
GetMessage(
"MAIN_ZIP_ERR_PARAM"));
565 return $arResultList;
576 $this->_errorReset();
584 [
'no_compression' =>
false,
587 'remove_all_path' =>
false,
588 'callback_pre_add' =>
'',
589 'callback_post_add' =>
'']) != 1)
595 if (is_array($arFileList))
597 $res = $this->_addData($arFileList, $arResultList,
$arParams);
601 if (is_string($arFileList))
603 $arTmpList = explode(
",", $arFileList);
604 $res = $this->_addData($arTmpList, $arResultList,
$arParams);
608 $this->_errorLog(
"ERR_PARAM_LIST",
GetMessage(
"MAIN_ZIP_ERR_PARAM_LIST"));
609 $res =
"ERR_PARAM_LIST";
618 return $arResultList;
627 $this->_errorReset();
629 if (!$this->_checkFormat())
635 if ($this->_getFileList($arTmpList) != 1)
651 $this->_errorReset();
653 if (!$this->_checkFormat())
664 [
'extract_as_string' =>
false,
667 'remove_all_path' =>
false,
668 'callback_pre_extract' =>
'',
669 'callback_post_extract' =>
'',
673 'by_preg' =>
'']) != 1)
679 if ($this->_extractByRule($arTmpList,
$arParams) != 1)
695 $this->_errorReset();
697 if (!$this->_checkFormat())
702 if ($this->_checkParams(
$arParams, [
'by_name' =>
'',
'by_index' =>
'',
'by_preg' =>
'']) != 1)
710 $this->_errorLog(
"ERR_PARAM_RULE",
GetMessage(
"MAIN_ZIP_ERR_PARAM_RULE"));
715 if ($this->_deleteByRule($arTmpList,
$arParams) != 1)
730 $this->_errorReset();
732 if (!$this->_checkFormat())
742 if (@is_file($this->io->GetPhysicalName($this->zipname)))
744 if (($this->zipfile = @fopen($this->io->GetPhysicalName($this->zipname),
'rb')) == 0)
746 $this->_errorLog(
"ERR_READ", str_replace(
"#FILE_NAME#",
removeDocRoot($this->zipname),
GetMessage(
"MAIN_ZIP_ERR_READ")));
751 $arCentralDirInfo = [];
752 if (($this->_readEndCentralDir($arCentralDirInfo)) != 1)
768 private function _checkFormat()
770 $this->_errorReset();
772 if (!is_file($this->io->GetPhysicalName($this->zipname)))
774 $this->_errorLog(
"ERR_MISSING_FILE", str_replace(
"#FILE_NAME#",
removeDocRoot($this->zipname),
GetMessage(
"MAIN_ZIP_ERR_MISSING_FILE")));
778 if (!is_readable($this->io->GetPhysicalName($this->zipname)))
780 $this->_errorLog(
"ERR_READ", str_replace(
"#FILE_NAME#",
removeDocRoot($this->zipname),
GetMessage(
"MAIN_ZIP_ERR_READ")));
788 private function _createArchive($arFilesList, &$arResultList, &
$arParams)
792 $removeAllDir =
$arParams[
'remove_all_path'];
794 if ((
$res = $this->_openFile(
'wb')) != 1)
799 $res = $this->_addList($arFilesList, $arResultList, $addDir, $removeDir, $removeAllDir,
$arParams);
806 private function _addData($arFilesList, &$arResultList, &
$arParams)
810 $removeAllDir =
$arParams[
'remove_all_path'];
812 if ((!is_file($this->io->GetPhysicalName($this->zipname))) || (filesize($this->io->GetPhysicalName($this->zipname)) == 0))
814 $res = $this->_createArchive($arFilesList, $arResultList,
$arParams);
818 if ((
$res = $this->_openFile(
'rb')) != 1)
823 $arCentralDirInfo = [];
824 if ((
$res = $this->_readEndCentralDir($arCentralDirInfo)) != 1)
830 @rewind($this->zipfile);
832 $zipname_tmp =
GetDirPath($this->zipname) . uniqid(
'ziparc') .
'.tmp';
834 if (($zipfile_tmp = @fopen($this->io->GetPhysicalName($zipname_tmp),
'wb')) == 0)
837 $this->_errorLog(
"ERR_READ_TMP", str_replace(
"#FILE_NAME#",
removeDocRoot($zipname_tmp),
GetMessage(
"MAIN_ZIP_ERR_READ_TMP")));
838 return $this->arErrors;
842 $size = $arCentralDirInfo[
'offset'];
845 $length = ($size < self::ReadBlockSize ? $size : self::ReadBlockSize);
847 $buffer = fread($this->zipfile, $length);
849 @fwrite($zipfile_tmp,
$buffer, $length);
855 $this->zipfile = $zipfile_tmp;
856 $zipfile_tmp = $tmp_id;
859 if ((
$res = $this->_addFileList($arFilesList, $arHeaders,
863 fclose($zipfile_tmp);
865 @unlink($this->io->GetPhysicalName($zipname_tmp));
871 $offset = @ftell($this->zipfile);
874 $size = $arCentralDirInfo[
'size'];
877 $length = ($size < self::ReadBlockSize ? $size : self::ReadBlockSize);
878 $buffer = @fread($zipfile_tmp, $length);
879 @fwrite($this->zipfile,
$buffer, $length);
887 if ($arHeaders[
$i][
'status'] ==
'ok')
889 if ((
$res = $this->_writeCentralFileHeader($arHeaders[
$i])) != 1)
891 fclose($zipfile_tmp);
893 @unlink($this->io->GetPhysicalName($zipname_tmp));
899 $this->_convertHeader2FileInfo($arHeaders[
$i], $arResultList[
$i]);
905 $size = @ftell($this->zipfile) - $offset;
908 if ((
$res = $this->_writeCentralHeader(
$counter + $arCentralDirInfo[
'entries'], $size, $offset, $zip_comment)) != 1)
917 $this->zipfile = $zipfile_tmp;
918 $zipfile_tmp = $tmp_id;
921 @fclose($zipfile_tmp);
922 @unlink($this->io->GetPhysicalName($this->zipname));
924 $this->_renameTmpFile($zipname_tmp, $this->zipname);
929 private function _openFile($mode)
933 if ($this->zipfile != 0)
935 $this->_errorLog(
"ERR_OPEN", str_replace(
"#FILE_NAME#",
removeDocRoot($this->zipname),
GetMessage(
"MAIN_ZIP_ERR_READ_OPEN")));
936 return $this->arErrors;
939 $this->_checkDirPath($this->zipname);
941 if (($this->zipfile = @fopen($this->io->GetPhysicalName($this->zipname), $mode)) == 0)
943 $this->_errorLog(
"ERR_READ_MODE", str_replace([
"#FILE_NAME#",
"#MODE#"], [
removeDocRoot($this->zipname), $mode],
GetMessage(
"MAIN_ZIP_ERR_READ_MODE")));
944 return $this->arErrors;
950 private function _closeFile()
952 if ($this->zipfile != 0)
954 @fclose($this->zipfile);
959 private function _addList($arFilesList, &$arResultList, $addDir, $removeDir, $removeAllDir, &
$arParams)
962 if ((
$res = $this->_addFileList($arFilesList, $arHeaders, $addDir, $removeDir, $removeAllDir,
$arParams)) != 1)
968 $offset = @ftell($this->zipfile);
973 if ($arHeaders[
$i][
'status'] ==
'ok')
975 if ((
$res = $this->_writeCentralFileHeader($arHeaders[
$i])) != 1)
981 $this->_convertHeader2FileInfo($arHeaders[
$i], $arResultList[
$i]);
987 $size = @ftell($this->zipfile) - $offset;
990 if ((
$res = $this->_writeCentralHeader(
$counter, $size, $offset, $zip_comment)) != 1)
998 private function _addFileList($arFilesList, &$arResultList, $addDir, $removeDir, $removeAllDir, &
$arParams)
1004 $count =
sizeof($arResultList);
1005 $filesListCount =
count($arFilesList);
1006 for ($j = 0; ($j < $filesListCount) && (
$res == 1); $j++)
1008 $filename = $this->_convertWinPath($arFilesList[$j],
false);
1016 if (!file_exists($this->io->GetPhysicalName(
$filename)))
1019 return $this->arErrors;
1022 if ((is_file($this->io->GetPhysicalName(
$filename))) || ((is_dir($this->io->GetPhysicalName(
$filename))) && !$removeAllDir))
1030 $arResultList[
$count++] = $header;
1033 if (is_dir($this->io->GetPhysicalName(
$filename)))
1045 $hdir = opendir($this->io->GetPhysicalName(
$filename));
1047 while ($hitem = readdir($hdir))
1049 if ($hitem ==
'.' || $hitem ==
'..')
1054 if (is_file($this->io->GetPhysicalName(
$path . $hitem)))
1056 if ((
$res = $this->_addFile(
$path . $hitem, $header, $addDir, $removeDir, $removeAllDir,
$arParams)) != 1)
1061 $arResultList[
$count++] = $header;
1066 $arTmpList[0] =
$path . $hitem;
1068 $res = $this->_addFileList($arTmpList, $arResultList, $addDir, $removeDir, $removeAllDir,
$arParams);
1069 $count =
sizeof($arResultList);
1083 private function _addFile(
$filename, &$arHeader, $addDir, $removeDir, $removeAllDir =
false,
$arParams = [])
1089 $this->_errorLog(
"ERR_PARAM_LIST",
GetMessage(
"MAIN_ZIP_ERR_PARAM_LIST"));
1090 return $this->arErrors;
1103 if ($removeDir !=
"")
1105 if (!str_ends_with($removeDir,
'/'))
1110 if ((str_starts_with(
$filename,
"./")) || (str_starts_with($removeDir,
"./")))
1112 if ((str_starts_with(
$filename,
"./")) && (!str_starts_with($removeDir,
"./")))
1114 $removeDir =
"./" . $removeDir;
1116 if ((!str_starts_with(
$filename,
"./")) && (str_starts_with($removeDir,
"./")))
1118 $removeDir = substr($removeDir, 2);
1122 $incl = $this->_containsPath($removeDir,
$filename);
1128 $storedFilename =
"";
1132 $storedFilename = mb_substr(
$filename, mb_strlen($removeDir));
1140 if (str_ends_with($addDir,
"/"))
1142 $storedFilename = $addDir . $storedFilename;
1146 $storedFilename = $addDir .
"/" . $storedFilename;
1151 $storedFilename = $this->_reducePath($storedFilename);
1155 $arHeader[
'comment'] =
'';
1156 $arHeader[
'comment_len'] = 0;
1157 $arHeader[
'compressed_size'] = 0;
1158 $arHeader[
'compression'] = 0;
1159 $arHeader[
'crc'] = 0;
1160 $arHeader[
'disk'] = 0;
1161 $arHeader[
'external'] = (is_file(
$filename) ? 0xFE49FFE0 : 0x41FF0010);
1162 $arHeader[
'extra'] =
'';
1163 $arHeader[
'extra_len'] = 0;
1164 $arHeader[
'filename'] = \Bitrix\Main\Text\Encoding::convertEncoding(
$filename, $this->fileSystemEncoding,
"cp866");
1165 $arHeader[
'filename_len'] = strlen(\Bitrix\Main\Text\Encoding::convertEncoding(
$filename, $this->fileSystemEncoding,
"cp866"));
1166 $arHeader[
'flag'] = 0;
1167 $arHeader[
'index'] = -1;
1168 $arHeader[
'internal'] = 0;
1169 $arHeader[
'mtime'] = filemtime(
$filename);
1170 $arHeader[
'offset'] = 0;
1171 $arHeader[
'size'] = filesize(
$filename);
1172 $arHeader[
'status'] =
'ok';
1173 $arHeader[
'stored_filename'] = \Bitrix\Main\Text\Encoding::convertEncoding($storedFilename, $this->fileSystemEncoding,
"cp866");
1174 $arHeader[
'version'] = 20;
1175 $arHeader[
'version_extracted'] = 10;
1181 $arLocalHeader = [];
1182 $this->_convertHeader2FileInfo($arHeader, $arLocalHeader);
1185 eval(
'$res = ' .
$arParams[
'callback_pre_add'] .
'(\'callback_pre_add\', $arLocalHeader);');
1189 $arHeader[
'status'] =
"skipped";
1194 if ($arHeader[
'stored_filename'] != $arLocalHeader[
'stored_filename'])
1196 $arHeader[
'stored_filename'] = $this->_reducePath($arLocalHeader[
'stored_filename']);
1201 if ($arHeader[
'stored_filename'] ==
"")
1203 $arHeader[
'status'] =
"filtered";
1207 if (mb_strlen($arHeader[
'stored_filename']) > 0xFF)
1209 $arHeader[
'status'] =
'filename_too_long';
1213 if ($arHeader[
'status'] ==
'ok')
1218 if (($file = @fopen(
$filename,
"rb")) == 0)
1221 return $this->arErrors;
1225 $content = $arHeader[
'size'] > 0 ? fread($file, $arHeader[
'size']) :
'';
1227 $arHeader[
'crc'] = crc32(
$content);
1232 $arHeader[
'compressed_size'] = strlen($compressedContent);
1233 $arHeader[
'compression'] = 8;
1236 if ((
$res = $this->_writeFileHeader($arHeader)) != 1)
1243 $binary_data = pack(
'a' . $arHeader[
'compressed_size'], $compressedContent);
1244 @fwrite($this->zipfile, $binary_data, $arHeader[
'compressed_size']);
1252 $arHeader[
'filename'] .=
'/';
1253 $arHeader[
'filename_len']++;
1254 $arHeader[
'size'] = 0;
1256 $arHeader[
'external'] = 0x41FF0010;
1259 if ((
$res = $this->_writeFileHeader($arHeader)) != 1)
1267 if ((isset(
$arParams[
'callback_post_add'])) && (
$arParams[
'callback_post_add'] !=
''))
1270 $arLocalHeader = [];
1271 $this->_convertHeader2FileInfo($arHeader, $arLocalHeader);
1274 eval(
'$res = ' .
$arParams[
'callback_post_add'] .
'(\'callback_post_add\', $arLocalHeader);');
1285 private function _writeFileHeader(&$arHeader)
1292 $arHeader[
'offset'] = ftell($this->zipfile);
1295 $date = getdate($arHeader[
'mtime']);
1296 $mtime = ($date[
'hours'] << 11) + ($date[
'minutes'] << 5) + $date[
'seconds'] / 2;
1297 $mdate = (($date[
'year'] - 1980) << 9) + ($date[
'mon'] << 5) + $date[
'mday'];
1302 $binary_data = pack(
"VvvvvvVVVvv",
1304 $arHeader[
'version'],
1306 $arHeader[
'compression'],
1310 $arHeader[
'compressed_size'],
1312 strlen($arHeader[
'stored_filename']),
1313 $arHeader[
'extra_len']
1317 fputs($this->zipfile, $binary_data, 30);
1320 if ($arHeader[
'stored_filename'] <>
'')
1322 fputs($this->zipfile, $arHeader[
'stored_filename'], strlen($arHeader[
'stored_filename']));
1324 if ($arHeader[
'extra_len'] != 0)
1326 fputs($this->zipfile, $arHeader[
'extra'], $arHeader[
'extra_len']);
1332 private function _writeCentralFileHeader($arHeader)
1339 $date = getdate($arHeader[
'mtime']);
1340 $mtime = ($date[
'hours'] << 11) + ($date[
'minutes'] << 5) + $date[
'seconds'] / 2;
1341 $mdate = (($date[
'year'] - 1980) << 9) + ($date[
'mon'] << 5) + $date[
'mday'];
1344 $binary_data = pack(
"VvvvvvvVVVvvvvvVV",
1346 $arHeader[
'version'],
1347 $arHeader[
'version_extracted'],
1349 $arHeader[
'compression'],
1353 $arHeader[
'compressed_size'],
1355 strlen($arHeader[
'stored_filename']),
1356 $arHeader[
'extra_len'],
1357 $arHeader[
'comment_len'],
1359 $arHeader[
'internal'],
1360 $arHeader[
'external'],
1361 $arHeader[
'offset']);
1364 fputs($this->zipfile, $binary_data, 46);
1367 if ($arHeader[
'stored_filename'] <>
'')
1369 fputs($this->zipfile, $arHeader[
'stored_filename'], strlen($arHeader[
'stored_filename']));
1371 if ($arHeader[
'extra_len'] != 0)
1373 fputs($this->zipfile, $arHeader[
'extra'], $arHeader[
'extra_len']);
1375 if ($arHeader[
'comment_len'] != 0)
1377 fputs($this->zipfile, $arHeader[
'comment'], $arHeader[
'comment_len']);
1383 private function _writeCentralHeader($entriesNumber, $blockSize, $offset,
$comment)
1388 $binary_data = pack(
"VvvvvVVv", 0x06054b50, 0, 0, $entriesNumber, $entriesNumber, $blockSize, $offset, mb_strlen(
$comment));
1391 fputs($this->zipfile, $binary_data, 22);
1402 private function _getFileList(&$arFilesList)
1404 if (($this->zipfile = @fopen($this->io->GetPhysicalName($this->zipname),
'rb')) == 0)
1406 $this->_errorLog(
"ERR_READ", str_replace(
"#FILE_NAME#",
removeDocRoot($this->zipname),
GetMessage(
"MAIN_ZIP_ERR_READ")));
1407 return $this->arErrors;
1411 $arCentralDirInfo = [];
1412 if ((
$res = $this->_readEndCentralDir($arCentralDirInfo)) != 1)
1418 @rewind($this->zipfile);
1420 if (@fseek($this->zipfile, $arCentralDirInfo[
'offset']))
1422 $this->_errorLog(
"ERR_INVALID_ARCHIVE_ZIP",
GetMessage(
"MAIN_ZIP_ERR_INVALID_ARCHIVE_ZIP"));
1423 return $this->arErrors;
1427 for (
$i = 0;
$i < $arCentralDirInfo[
'entries'];
$i++)
1430 if ((
$res = $this->_readCentralFileHeader($header)) != 1)
1434 $header[
'index'] =
$i;
1437 $this->_convertHeader2FileInfo($header, $arFilesList[
$i]);
1441 $this->_closeFile();
1445 private function _convertHeader2FileInfo($arHeader, &$arInfo)
1451 $arInfo[
'filename'] = $arHeader[
'filename'];
1452 $arInfo[
'stored_filename'] = $arHeader[
'stored_filename'];
1453 $arInfo[
'size'] = $arHeader[
'size'];
1454 $arInfo[
'compressed_size'] = $arHeader[
'compressed_size'];
1455 $arInfo[
'mtime'] = $arHeader[
'mtime'];
1456 $arInfo[
'comment'] = $arHeader[
'comment'];
1457 $arInfo[
'folder'] = (($arHeader[
'external'] & 0x00000010) == 0x00000010);
1458 $arInfo[
'index'] = $arHeader[
'index'];
1459 $arInfo[
'status'] = $arHeader[
'status'];
1464 private function _extractByRule(&$arFileList, &
$arParams)
1468 $removeAllPath =
$arParams[
'remove_all_path'];
1471 if ((
$path ==
"") || ((!str_starts_with(
$path,
"/")) && (!str_starts_with(
$path,
"../")) && (mb_substr(
$path, 1, 2) !=
":/")))
1480 while (str_ends_with(
$path,
"/"))
1487 if (($removePath !=
"") && (!str_ends_with($removePath,
'/')))
1492 if ((
$res = $this->_openFile(
'rb')) != 1)
1498 $arCentralDirInfo = [];
1499 if ((
$res = $this->_readEndCentralDir($arCentralDirInfo)) != 1)
1501 $this->_closeFile();
1506 $entryPos = $arCentralDirInfo[
'offset'];
1511 for (
$i = 0, $extractedCounter = 0;
$i < $arCentralDirInfo[
'entries'];
$i++)
1514 @rewind($this->zipfile);
1515 if (@fseek($this->zipfile, $entryPos))
1517 $this->_closeFile();
1518 $this->_errorLog(
"ERR_INVALID_ARCHIVE_ZIP",
GetMessage(
"MAIN_ZIP_ERR_MISSING_FILE"));
1519 return $this->arErrors;
1524 if ((
$res = $this->_readCentralFileHeader($header)) != 1)
1526 $this->_closeFile();
1531 $header[
'index'] =
$i;
1534 $entryPos = ftell($this->zipfile);
1543 for ($j = 0; $j <
$count && !$extract; $j++)
1546 if (str_ends_with(
$arParams[
'by_name'][$j],
"/"))
1549 if ((mb_strlen($header[
'stored_filename']) > mb_strlen(
$arParams[
'by_name'][$j]))
1550 && (str_starts_with($header[
'stored_filename'],
$arParams[
'by_name'][$j])))
1557 if ($header[
'stored_filename'] ==
$arParams[
'by_name'][$j])
1569 if (preg_match(
$arParams[
'by_preg'], $header[
'stored_filename']))
1607 @rewind($this->zipfile);
1608 if (@fseek($this->zipfile, $header[
'offset']))
1610 $this->_closeFile();
1611 $this->_errorLog(
"ERR_INVALID_ARCHIVE_ZIP",
GetMessage(
"MAIN_ZIP_ERR_INVALID_ARCHIVE_ZIP"));
1612 return $this->arErrors;
1618 if ((
$res = $this->_extractFileAsString($header, $string)) != 1)
1620 $this->_closeFile();
1625 if ((
$res = $this->_convertHeader2FileInfo($header, $arFileList[$extractedCounter])) != 1)
1627 $this->_closeFile();
1632 $arFileList[$extractedCounter][
'content'] = $string;
1635 $extractedCounter++;
1639 if ((
$res = $this->_extractFile($header,
$path, $removePath, $removeAllPath,
$arParams)) != 1)
1641 $this->_closeFile();
1646 if ((
$res = $this->_convertHeader2FileInfo($header, $arFileList[$extractedCounter++])) != 1)
1648 $this->_closeFile();
1654 $this->_closeFile();
1658 private function _extractFile(&$arEntry,
$path, $removePath, $removeAllPath,
$arParams)
1660 if ((
$res = $this->_readFileHeader($header)) != 1)
1666 $arEntry[
"filename"] = \Bitrix\Main\Text\Encoding::convertEncoding($arEntry[
"filename"],
"cp866", $this->fileSystemEncoding);
1667 $arEntry[
"stored_filename"] = \Bitrix\Main\Text\Encoding::convertEncoding($arEntry[
"stored_filename"],
"cp866", $this->fileSystemEncoding);
1672 $arEntry[
'stored_filename'] =
_normalizePath($arEntry[
'stored_filename']);
1676 $arEntry[
'filename'] = basename($arEntry[
'filename']);
1680 if ($removePath !=
"")
1682 if ($this->_containsPath($removePath, $arEntry[
'filename']) == 2)
1685 $arEntry[
'status'] =
"filtered";
1689 if (str_starts_with($arEntry[
'filename'], $removePath))
1692 $arEntry[
'filename'] = substr($arEntry[
'filename'], strlen($removePath));
1700 $arEntry[
'filename'] =
$path .
"/" . $arEntry[
'filename'];
1704 if ((isset(
$arParams[
'callback_pre_extract']))
1705 && (
$arParams[
'callback_pre_extract'] !=
''))
1708 $arLocalHeader = [];
1709 $this->_convertHeader2FileInfo($arEntry, $arLocalHeader);
1712 eval(
'$res = ' .
$arParams[
'callback_pre_extract'] .
'(\'callback_pre_extract\', $arLocalHeader);');
1717 $arEntry[
'status'] =
"skipped";
1722 $arEntry[
'filename'] = $arLocalHeader[
'filename'];
1726 if ($arEntry[
'status'] ==
'ok')
1730 $arEntry[
'status'] =
"no_permissions";
1735 if (file_exists($arEntry[
'filename']))
1737 if (is_dir($arEntry[
'filename']))
1739 $arEntry[
'status'] =
"already_a_directory";
1743 if (!is_writeable($arEntry[
'filename']))
1745 $arEntry[
'status'] =
"write_protected";
1749 if ((filemtime($arEntry[
'filename']) > $arEntry[
'mtime']) && (!$this->replaceExistentFiles))
1751 $arEntry[
'status'] =
"newer_exist";
1759 if ((($arEntry[
'external'] & 0x00000010) == 0x00000010) || (str_ends_with($arEntry[
'filename'],
'/')))
1761 $checkDir = $arEntry[
'filename'];
1765 if (!mb_strstr($arEntry[
'filename'],
"/"))
1771 $checkDir = dirname($arEntry[
'filename']);
1775 if ((
$res = $this->_checkDir($checkDir, (($arEntry[
'external'] & 0x00000010) == 0x00000010))) != 1)
1778 $arEntry[
'status'] =
"path_creation_fail";
1788 if ($arEntry[
'status'] ==
'ok')
1791 if (!(($arEntry[
'external'] & 0x00000010) == 0x00000010))
1794 if (($arEntry[
'compression'] == 0) && ($arEntry[
'compressed_size'] == $arEntry[
'size']))
1796 if (($destFile = @fopen($arEntry[
'filename'],
'wb')) == 0)
1798 $arEntry[
'status'] =
"write_error";
1803 $size = $arEntry[
'compressed_size'];
1806 $length = ($size < self::ReadBlockSize ? $size : self::ReadBlockSize);
1807 $buffer = fread($this->zipfile, $length);
1808 $binary_data = pack(
'a' . $length,
$buffer);
1809 @fwrite($destFile, $binary_data, $length);
1817 touch($arEntry[
'filename'], $arEntry[
'mtime']);
1821 if (($destFile = @fopen($arEntry[
'filename'],
'wb')) == 0)
1824 $arEntry[
'status'] =
"write_error";
1829 $buffer = @fread($this->zipfile, $arEntry[
'compressed_size']);
1839 touch($arEntry[
'filename'], $arEntry[
'mtime']);
1844 chmod($arEntry[
'filename'],
$arParams[
'set_chmod']);
1850 if ((isset(
$arParams[
'callback_post_extract'])) && (
$arParams[
'callback_post_extract'] !=
''))
1853 $arLocalHeader = [];
1854 $this->_convertHeader2FileInfo($arEntry, $arLocalHeader);
1857 eval(
'$res = ' .
$arParams[
'callback_post_extract'] .
'(\'callback_post_extract\', $arLocalHeader);');
1862 private function _extractFileAsString($arEntry, &$string)
1866 if ((
$res = $this->_readFileHeader($header)) != 1)
1874 if (!(($arEntry[
'external'] & 0x00000010) == 0x00000010))
1877 if ($arEntry[
'compressed_size'] == $arEntry[
'size'])
1879 $string = fread($this->zipfile, $arEntry[
'compressed_size']);
1883 $data = fread($this->zipfile, $arEntry[
'compressed_size']);
1884 $string = gzinflate(
$data);
1889 $this->_errorLog(
"ERR_EXTRACT",
GetMessage(
"MAIN_ZIP_ERR_EXTRACT"));
1890 return $this->arErrors;
1896 private function _readFileHeader(&$arHeader)
1901 $binary_data = @fread($this->zipfile, 4);
1903 $data = unpack(
'Vid', $binary_data);
1906 if (
$data[
'id'] != 0x04034b50)
1908 $this->_errorLog(
"ERR_BAD_FORMAT",
GetMessage(
"MAIN_ZIP_ERR_STRUCT"));
1909 return $this->arErrors;
1913 $binary_data = fread($this->zipfile, 26);
1916 if (strlen($binary_data) != 26)
1918 $arHeader[
'filename'] =
"";
1919 $arHeader[
'status'] =
"invalid_header";
1921 $this->_errorLog(
"ERR_BAD_BLOCK_SIZE", str_replace(
"#BLOCK_SIZE#", $binary_data,
GetMessage(
"MAIN_ZIP_ERR_BLOCK_SIZE")));
1922 return $this->arErrors;
1926 $data = unpack(
'vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $binary_data);
1928 $arHeader[
'filename'] = fread($this->zipfile,
$data[
'filename_len']);
1931 if (
$data[
'extra_len'] != 0)
1933 $arHeader[
'extra'] = fread($this->zipfile,
$data[
'extra_len']);
1937 $arHeader[
'extra'] =
'';
1941 $arHeader[
'compression'] =
$data[
'compression'];
1942 $arHeader[
'size'] =
$data[
'size'];
1943 $arHeader[
'compressed_size'] =
$data[
'compressed_size'];
1944 $arHeader[
'crc'] =
$data[
'crc'];
1945 $arHeader[
'flag'] =
$data[
'flag'];
1948 $arHeader[
'mdate'] =
$data[
'mdate'];
1949 $arHeader[
'mtime'] =
$data[
'mtime'];
1951 if ($arHeader[
'mdate'] && $arHeader[
'mtime'])
1954 $hour = ($arHeader[
'mtime'] & 0xF800) >> 11;
1955 $min = ($arHeader[
'mtime'] & 0x07E0) >> 5;
1956 $sec = ($arHeader[
'mtime'] & 0x001F) * 2;
1959 $year = (($arHeader[
'mdate'] & 0xFE00) >> 9) + 1980;
1960 $month = ($arHeader[
'mdate'] & 0x01E0) >> 5;
1961 $day = $arHeader[
'mdate'] & 0x001F;
1964 $arHeader[
'mtime'] = mktime($hour, $min, $sec, $month, $day,
$year);
1968 $arHeader[
'mtime'] = time();
1972 $arHeader[
'stored_filename'] = $arHeader[
'filename'];
1973 $arHeader[
'status'] =
"ok";
1978 private function _readCentralFileHeader(&$arHeader)
1983 $binary_data = @fread($this->zipfile, 4);
1985 $data = unpack(
'Vid', $binary_data);
1988 if (
$data[
'id'] != 0x02014b50)
1990 $this->_errorLog(
"ERR_BAD_FORMAT",
GetMessage(
"MAIN_ZIP_ERR_STRUCT"));
1991 return $this->arErrors;
1995 $binary_data = fread($this->zipfile, 42);
1998 if (strlen($binary_data) != 42)
2000 $arHeader[
'filename'] =
"";
2001 $arHeader[
'status'] =
"invalid_header";
2003 $this->_errorLog(
"ERR_BAD_BLOCK_SIZE", str_replace(
"#SIZE#", $binary_data,
GetMessage(
"MAIN_ZIP_ERR_BLOCK_SIZE")));
2004 return $this->arErrors;
2008 $arHeader = unpack(
'vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $binary_data);
2011 if ($arHeader[
'filename_len'] != 0)
2013 $arHeader[
'filename'] = fread($this->zipfile, $arHeader[
'filename_len']);
2017 $arHeader[
'filename'] =
'';
2021 if ($arHeader[
'extra_len'] != 0)
2023 $arHeader[
'extra'] = fread($this->zipfile, $arHeader[
'extra_len']);
2027 $arHeader[
'extra'] =
'';
2031 if ($arHeader[
'comment_len'] != 0)
2033 $arHeader[
'comment'] = fread($this->zipfile, $arHeader[
'comment_len']);
2037 $arHeader[
'comment'] =
'';
2043 if ($arHeader[
'mdate'] && $arHeader[
'mtime'])
2046 $hour = ($arHeader[
'mtime'] & 0xF800) >> 11;
2047 $min = ($arHeader[
'mtime'] & 0x07E0) >> 5;
2048 $sec = ($arHeader[
'mtime'] & 0x001F) * 2;
2051 $year = (($arHeader[
'mdate'] & 0xFE00) >> 9) + 1980;
2052 $month = ($arHeader[
'mdate'] & 0x01E0) >> 5;
2053 $day = $arHeader[
'mdate'] & 0x001F;
2056 $arHeader[
'mtime'] = mktime($hour, $min, $sec, $month, $day,
$year);
2060 $arHeader[
'mtime'] = time();
2064 $arHeader[
'stored_filename'] = $arHeader[
'filename'];
2067 $arHeader[
'status'] =
'ok';
2070 if (str_ends_with($arHeader[
'filename'],
'/'))
2072 $arHeader[
'external'] = 0x41FF0010;
2078 private function _readEndCentralDir(&$arCentralDir)
2083 $size = filesize($this->io->GetPhysicalName($this->zipname));
2084 @fseek($this->zipfile, $size);
2086 if (@ftell($this->zipfile) != $size)
2088 $this->_errorLog(
"ERR_ARC_END", str_replace(
"#FILE_NAME#",
removeDocRoot($this->zipname),
GetMessage(
"MAIN_ZIP_ERR_ARC_END")));
2089 return $this->arErrors;
2098 @fseek($this->zipfile, $size - 22);
2100 if (@ftell($this->zipfile) != ($size - 22))
2102 $this->_errorLog(
"ERR_ARC_MID", str_replace(
"#FILE_NAME#",
removeDocRoot($this->zipname),
GetMessage(
"MAIN_ZIP_ERR_ARC_MID")));
2103 return $this->arErrors;
2107 $binary_data = @fread($this->zipfile, 4);
2108 $data = unpack(
'Vid', $binary_data);
2111 if (
$data[
'id'] == 0x06054b50)
2116 $pos = ftell($this->zipfile);
2124 if ($maxSize > $size)
2129 @fseek($this->zipfile, $size - $maxSize);
2131 if (@ftell($this->zipfile) != ($size - $maxSize))
2133 $this->_errorLog(
"ERR_ARC_MID", str_replace(
"#FILE_NAME#",
removeDocRoot($this->zipname),
GetMessage(
"MAIN_ZIP_ERR_ARC_MID")));
2134 return $this->arErrors;
2138 $pos = ftell($this->zipfile);
2140 while ($pos < $size)
2143 $byte = @fread($this->zipfile, 1);
2145 $bytes = (
$bytes << (8 * (PHP_INT_SIZE - 3))) >> (8 * (PHP_INT_SIZE - 4));
2149 if (
$bytes == 0x504b0506)
2161 $this->_errorLog(
"ERR_ARC_MID_END",
GetMessage(
"MAIN_ZIP_ERR_ARC_MID_END"));
2162 return $this->arErrors;
2167 $binary_data = fread($this->zipfile, 18);
2170 if (strlen($binary_data) != 18)
2172 $this->_errorLog(
"ERR_ARC_END_SIZE", str_replace(
"#SIZE#", mb_strlen($binary_data),
GetMessage(
"MAIN_ZIP_ERR_ARC_END_SIZE")));
2173 return $this->arErrors;
2177 $data = unpack(
'vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $binary_data);
2180 if (($pos +
$data[
'comment_size'] + 18) != $size)
2182 $this->_errorLog(
"ERR_SIGNATURE",
GetMessage(
"MAIN_ZIP_ERR_SIGNATURE"));
2183 return $this->arErrors;
2187 if (
$data[
'comment_size'] != 0)
2189 $arCentralDir[
'comment'] = fread($this->zipfile,
$data[
'comment_size']);
2193 $arCentralDir[
'comment'] =
'';
2196 $arCentralDir[
'entries'] =
$data[
'entries'];
2197 $arCentralDir[
'disk_entries'] =
$data[
'disk_entries'];
2198 $arCentralDir[
'offset'] =
$data[
'offset'];
2199 $arCentralDir[
'size'] =
$data[
'size'];
2200 $arCentralDir[
'disk'] =
$data[
'disk'];
2201 $arCentralDir[
'disk_start'] =
$data[
'disk_start'];
2206 private function _deleteByRule(&$arResultList,
$arParams)
2208 $arCentralDirInfo = [];
2211 if ((
$res = $this->_openFile(
'rb')) != 1)
2216 if ((
$res = $this->_readEndCentralDir($arCentralDirInfo)) != 1)
2218 $this->_closeFile();
2223 $entryPos = $arCentralDirInfo[
'offset'];
2224 @rewind($this->zipfile);
2226 if (@fseek($this->zipfile, $entryPos))
2229 $this->_closeFile();
2230 $this->_errorLog(
"ERR_INVALID_ARCHIVE_ZIP",
GetMessage(
"MAIN_ZIP_ERR_INVALID_ARCHIVE_ZIP"));
2231 return $this->arErrors;
2237 for (
$i = 0, $extractedCounter = 0;
$i < $arCentralDirInfo[
'entries'];
$i++)
2240 $arHeaders[$extractedCounter] = [];
2242 $res = $this->_readCentralFileHeader($arHeaders[$extractedCounter]);
2245 $this->_closeFile();
2250 $arHeaders[$extractedCounter][
'index'] =
$i;
2261 if (str_ends_with(
$arParams[
'by_name'][$j],
"/"))
2264 if ((mb_strlen($arHeaders[$extractedCounter][
'stored_filename']) > mb_strlen(
$arParams[
'by_name'][$j]))
2265 && (str_starts_with($arHeaders[$extractedCounter][
'stored_filename'],
$arParams[
'by_name'][$j])))
2269 elseif ((($arHeaders[$extractedCounter][
'external'] & 0x00000010) == 0x00000010)
2270 && ($arHeaders[$extractedCounter][
'stored_filename'] .
'/' ==
$arParams[
'by_name'][$j]))
2275 elseif ($arHeaders[$extractedCounter][
'stored_filename'] ==
$arParams[
'by_name'][$j])
2286 if (preg_match(
$arParams[
'by_preg'], $arHeaders[$extractedCounter][
'stored_filename']))
2319 unset($arHeaders[$extractedCounter]);
2323 $extractedCounter++;
2328 if ($extractedCounter > 0)
2331 $zipname_tmp =
GetDirPath($this->zipname) . uniqid(
'ziparc') .
'.tmp';
2333 $tmpzip =
new CZip($zipname_tmp);
2335 if ((
$res = $tmpzip->_openFile(
'wb')) != 1)
2337 $this->_closeFile();
2342 for (
$i = 0;
$i <
sizeof($arHeaders);
$i++)
2345 @rewind($this->zipfile);
2346 if (@fseek($this->zipfile, $arHeaders[
$i][
'offset']))
2348 $this->_closeFile();
2349 $tmpzip->_closeFile();
2350 @unlink($this->io->GetPhysicalName($zipname_tmp));
2351 $this->_errorLog(
"ERR_INVALID_ARCHIVE_ZIP",
GetMessage(
"MAIN_ZIP_ERR_INVALID_ARCHIVE_ZIP"));
2353 return $this->arErrors;
2356 if ((
$res = $this->_readFileHeader($arHeaders[
$i])) != 1)
2358 $this->_closeFile();
2359 $tmpzip->_closeFile();
2360 @unlink($this->io->GetPhysicalName($zipname_tmp));
2366 $res = $tmpzip->_writeFileHeader($arHeaders[
$i]);
2369 $this->_closeFile();
2370 $tmpzip->_closeFile();
2371 @unlink($this->io->GetPhysicalName($zipname_tmp));
2377 $res = $this->_copyBlocks($this->zipfile, $tmpzip->zipfile, $arHeaders[
$i][
'compressed_size']);
2380 $this->_closeFile();
2381 $tmpzip->_closeFile();
2382 @unlink($this->io->GetPhysicalName($zipname_tmp));
2389 $offset = @ftell($tmpzip->zipfile);
2392 for (
$i = 0;
$i <
sizeof($arHeaders);
$i++)
2394 $res = $tmpzip->_writeCentralFileHeader($arHeaders[
$i]);
2397 $tmpzip->_closeFile();
2398 $this->_closeFile();
2399 @unlink($this->io->GetPhysicalName($zipname_tmp));
2405 $tmpzip->_convertHeader2FileInfo($arHeaders[
$i], $arResultList[
$i]);
2409 $size = @ftell($tmpzip->zipfile) - $offset;
2411 $res = $tmpzip->_writeCentralHeader(
sizeof($arHeaders), $size, $offset, $zip_comment);
2415 $tmpzip->_closeFile();
2416 $this->_closeFile();
2417 @unlink($this->io->GetPhysicalName($zipname_tmp));
2422 $tmpzip->_closeFile();
2423 $this->_closeFile();
2426 @unlink($this->io->GetPhysicalName($this->zipname));
2429 $this->_renameTmpFile($zipname_tmp, $this->zipname);
2437 private function _checkDir(
$dir, $isDir =
false)
2442 if (($isDir) && (str_ends_with(
$dir,
'/')))
2448 if ((is_dir(
$dir)) || (
$dir ==
""))
2454 $parentDir = dirname(
$dir);
2456 if ($parentDir !=
$dir)
2459 if ($parentDir !=
"")
2461 if ((
$res = $this->_checkDir($parentDir)) != 1)
2471 $this->_errorLog(
"ERR_DIR_CREATE_FAIL", str_replace(
"#DIR_NAME#",
$dir,
GetMessage(
"MAIN_ZIP_ERR_DIR_CREATE_FAIL")));
2472 return $this->arErrors;
2482 $this->_errorLog(
"ERR_PARAM",
GetMessage(
"MAIN_ZIP_ERR_PARAM"));
2483 return $this->arErrors;
2491 $this->_errorLog(
"ERR_PARAM_KEY", str_replace(
"#KEY#",
$key,
GetMessage(
"MAIN_ZIP_ERR_PARAM_KEY")));
2492 return $this->arErrors;
2506 $arCallbacks = [
'callback_pre_add',
'callback_post_add',
'callback_pre_extract',
'callback_post_extract'];
2516 $this->_errorLog(
"ERR_PARAM_CALLBACK", str_replace([
"#CALLBACK#",
"#PARAM_NAME#"], [
$arParams[
$key],
$key],
GetMessage(
"MAIN_ZIP_ERR_PARAM_CALLBACK")));
2517 return $this->arErrors;
2525 private function _errorLog($errorName, $errorString =
'')
2527 $this->arErrors[] =
"[" . $errorName .
"] " . $errorString;
2530 private function _errorReset()
2532 $this->arErrors = [];
2535 private function _reducePath(
$dir)
2542 $arTmpList = explode(
"/",
$dir);
2545 for (
$i =
sizeof($arTmpList) - 1;
$i >= 0;
$i--)
2548 if ($arTmpList[
$i] ==
".")
2554 if ($arTmpList[
$i] ==
"..")
2561 if (($arTmpList[
$i] ==
"") && (
$i != (
sizeof($arTmpList) - 1)) && (
$i != 0))
2567 $res = $arTmpList[
$i] . (
$i != (
sizeof($arTmpList) - 1) ?
"/" .
$res :
"");
2576 private function _containsPath(
$dir,
$path)
2581 $arTmpDirList = explode(
"/",
$dir);
2582 $arTmpPathList = explode(
"/",
$path);
2584 $arTmpDirListSize =
sizeof($arTmpDirList);
2585 $arTmpPathListSize =
sizeof($arTmpPathList);
2591 while ((
$i < $arTmpDirListSize) && ($j < $arTmpPathListSize) && (
$res))
2594 if ($arTmpDirList[
$i] ==
'')
2600 if ($arTmpPathList[$j] ==
'')
2607 if ($arTmpDirList[
$i] != $arTmpPathList[$j])
2620 while (($j < $arTmpPathListSize) && ($arTmpPathList[$j] ==
''))
2625 while ((
$i < $arTmpDirListSize) && ($arTmpDirList[
$i] ==
''))
2630 if ((
$i >= $arTmpDirListSize) && ($j >= $arTmpPathListSize))
2637 if (
$i < $arTmpDirListSize)
2648 private function _copyBlocks($source,
$dest, $blockSize, $mode = 0)
2654 while ($blockSize != 0)
2656 $length = ($blockSize < self::ReadBlockSize ? $blockSize : self::ReadBlockSize);
2657 $buffer = @fread($source, $length);
2659 $blockSize -= $length;
2666 while ($blockSize != 0)
2668 $length = ($blockSize < self::ReadBlockSize ? $blockSize : self::ReadBlockSize);
2669 $buffer = @gzread($source, $length);
2671 $blockSize -= $length;
2678 while ($blockSize != 0)
2680 $length = ($blockSize < self::ReadBlockSize ? $blockSize : self::ReadBlockSize);
2681 $buffer = @fread($source, $length);
2683 $blockSize -= $length;
2690 while ($blockSize != 0)
2692 $length = ($blockSize < self::ReadBlockSize ? $blockSize : self::ReadBlockSize);
2693 $buffer = @gzread($source, $length);
2695 $blockSize -= $length;
2705 private function _renameTmpFile($source,
$dest)
2709 if (!@rename($this->io->GetPhysicalName($source), $this->io->GetPhysicalName(
$dest)))
2711 if (!@copy($this->io->GetPhysicalName($source), $this->io->GetPhysicalName(
$dest)))
2717 if (!@unlink($this->io->GetPhysicalName($source)))
2727 private function _convertWinPath(
$path, $removeDiskLetter =
true)
2729 if (mb_stristr(php_uname(),
'windows'))
2732 if ($removeDiskLetter && ($position = mb_strpos(
$path,
':')) !==
false)
2738 if ((strpos(
$path,
'\\') > 0) || (str_starts_with(
$path,
'\\')))
2747 private function _parseFileParams($arFileList)
2749 if (isset($arFileList) && is_array($arFileList))
2754 if (isset($arFileList) && $arFileList <>
'')
2756 if (str_starts_with($arFileList,
"\""))
2758 return [trim($arFileList,
"\"")];
2760 return explode(
" ", $arFileList);
2766 private function _cleanFile()
2768 $this->_closeFile();
2769 @unlink($this->io->GetPhysicalName($this->zipname));
2772 private function _checkDirPath(
$path)
2774 $path = str_replace([
"\\",
"//"],
"/",
$path);
2777 if (!str_ends_with(
$path,
"/"))
2785 if (!file_exists($this->io->GetPhysicalName(
$path)))
2787 return mkdir($this->io->GetPhysicalName(
$path), BX_DIR_PERMISSIONS,
true);
2791 return is_dir($this->io->GetPhysicalName(
$path));
2795 private function _getfileSystemEncoding()
2797 $fileSystemEncoding = mb_strtolower(defined(
"BX_FILE_SYSTEM_ENCODING") ? BX_FILE_SYSTEM_ENCODING :
"");
2799 if (empty($fileSystemEncoding))
2801 if (mb_strtoupper(mb_substr(PHP_OS, 0, 3)) ===
"WIN")
2803 $fileSystemEncoding =
"windows-1251";
2807 $fileSystemEncoding =
"utf-8";
2811 return $fileSystemEncoding;