- Модуль: main
- Путь к файлу: ~/bitrix/modules/main/classes/general/zip.php
- Класс: CZip
- Вызов: CZip::_extractByRule
private function _extractByRule(&$arFileList, &$arParams)
{
$path = $arParams['add_path'];
$removePath = $arParams['remove_path'];
$removeAllPath = $arParams['remove_all_path'];
//path checking
if (($path == "") || ((mb_substr($path, 0, 1) != "/") && (mb_substr($path, 0, 3) != "../") && (mb_substr($path, 1, 2) != ":/")))
{
$path = "./" . $path;
}
//reduce the path last (and duplicated) '/'
if (($path != "./") && ($path != "/"))
{
// checking path end '/'
while (mb_substr($path, -1) == "/")
{
$path = mb_substr($path, 0, mb_strlen($path) - 1);
}
}
//path should end with the /
if (($removePath != "") && (mb_substr($removePath, -1) != '/'))
{
$removePath .= '/';
}
if (($res = $this->_openFile('rb')) != 1)
{
return $res;
}
//reading central directory information
$arCentralDirInfo = [];
if (($res = $this->_readEndCentralDir($arCentralDirInfo)) != 1)
{
$this->_closeFile();
return $res;
}
//starting from the beginning of the central directory
$entryPos = $arCentralDirInfo['offset'];
//reading each entry
$j_start = 0;
for ($i = 0, $extractedCounter = 0; $i < $arCentralDirInfo['entries']; $i++)
{
//reading next central directory record
@rewind($this->zipfile);
if (@fseek($this->zipfile, $entryPos))
{
$this->_closeFile();
$this->_errorLog("ERR_INVALID_ARCHIVE_ZIP", GetMessage("MAIN_ZIP_ERR_MISSING_FILE"));
return $this->arErrors;
}
//reading the file header
$header = [];
if (($res = $this->_readCentralFileHeader($header)) != 1)
{
$this->_closeFile();
return $res;
}
//saving the index
$header['index'] = $i;
//saving the file pos
$entryPos = ftell($this->zipfile);
$extract = false;
//look for the specific extract rules
if ((isset($arParams['by_name'])) && is_array($arParams['by_name']))
{
//is filename in the list
$count = count($arParams['by_name']);
for ($j = 0; $j < $count && !$extract; $j++)
{
//is directory
if (mb_substr($arParams['by_name'][$j], -1) == "/")
{
//is dir in the filename path
if ((mb_strlen($header['stored_filename']) > mb_strlen($arParams['by_name'][$j]))
&& (mb_substr($header['stored_filename'], 0, mb_strlen($arParams['by_name'][$j])) == $arParams['by_name'][$j]))
{
$extract = true;
}
}
else
{
if ($header['stored_filename'] == $arParams['by_name'][$j])
{
$extract = true;
}
}
}
}
else
{
if ((isset($arParams['by_preg'])) && ($arParams['by_preg'] != ""))
{
//extract by preg rule
if (preg_match($arParams['by_preg'], $header['stored_filename']))
{
$extract = true;
}
}
else
{
if ((isset($arParams['by_index'])) && is_array($arParams['by_index']))
{
//extract by index rule (if index is in the list)
for ($j = $j_start, $n = count($arParams['by_index']); $j < $n && !$extract; $j++)
{
if (($i >= $arParams['by_index'][$j]['start']) && ($i <= $arParams['by_index'][$j]['end']))
{
$extract = true;
}
if ($i >= $arParams['by_index'][$j]['end'])
{
$j_start = $j + 1;
}
if ($arParams['by_index'][$j]['start'] > $i)
{
break;
}
}
}
else
{
$extract = true;
}
}
}
// extract file
if ($extract)
{
@rewind($this->zipfile);
if (@fseek($this->zipfile, $header['offset']))
{
$this->_closeFile();
$this->_errorLog("ERR_INVALID_ARCHIVE_ZIP", GetMessage("MAIN_ZIP_ERR_INVALID_ARCHIVE_ZIP"));
return $this->arErrors;
}
//extract as a string
if ($arParams['extract_as_string'])
{
//extract the file
if (($res = $this->_extractFileAsString($header, $string)) != 1)
{
$this->_closeFile();
return $res;
}
//get attributes
if (($res = $this->_convertHeader2FileInfo($header, $arFileList[$extractedCounter])) != 1)
{
$this->_closeFile();
return $res;
}
//set file content
$arFileList[$extractedCounter]['content'] = $string;
//next extracted file
$extractedCounter++;
}
else
{
if (($res = $this->_extractFile($header, $path, $removePath, $removeAllPath, $arParams)) != 1)
{
$this->_closeFile();
return $res;
}
//get attributes
if (($res = $this->_convertHeader2FileInfo($header, $arFileList[$extractedCounter++])) != 1)
{
$this->_closeFile();
return $res;
}
}
}
}
$this->_closeFile();
return $res;
}