- Модуль: main
- Путь к файлу: ~/bitrix/modules/main/classes/general/zip.php
- Класс: CZip
- Вызов: CZip::_deleteByRule
private function _deleteByRule(&$arResultList, $arParams)
{
$arCentralDirInfo = [];
$arHeaders = [];
if (($res = $this->_openFile('rb')) != 1)
{
return $res;
}
if (($res = $this->_readEndCentralDir($arCentralDirInfo)) != 1)
{
$this->_closeFile();
return $res;
}
//scanning all the files, starting at the beginning of Central Dir
$entryPos = $arCentralDirInfo['offset'];
@rewind($this->zipfile);
if (@fseek($this->zipfile, $entryPos))
{
//clean file
$this->_closeFile();
$this->_errorLog("ERR_INVALID_ARCHIVE_ZIP", GetMessage("MAIN_ZIP_ERR_INVALID_ARCHIVE_ZIP"));
return $this->arErrors;
}
$j_start = 0;
//reading each entry
for ($i = 0, $extractedCounter = 0; $i < $arCentralDirInfo['entries']; $i++)
{
//reading file header
$arHeaders[$extractedCounter] = [];
$res = $this->_readCentralFileHeader($arHeaders[$extractedCounter]);
if ($res != 1)
{
$this->_closeFile();
return $res;
}
//saving index
$arHeaders[$extractedCounter]['index'] = $i;
//check specific extract rules
$isFound = false;
//name rule
if ((isset($arParams['by_name'])) && is_array($arParams['by_name']))
{
//if the filename is in the list
for ($j = 0, $n = count($arParams['by_name']); $j < $n && !$isFound; $j++)
{
if (mb_substr($arParams['by_name'][$j], -1) == "/")
{
//if the directory is in the filename path
if ((mb_strlen($arHeaders[$extractedCounter]['stored_filename']) > mb_strlen($arParams['by_name'][$j]))
&& (mb_substr($arHeaders[$extractedCounter]['stored_filename'], 0, mb_strlen($arParams['by_name'][$j])) == $arParams['by_name'][$j]))
{
$isFound = true;
}
elseif ((($arHeaders[$extractedCounter]['external'] & 0x00000010) == 0x00000010) /* Indicates a folder */
&& ($arHeaders[$extractedCounter]['stored_filename'] . '/' == $arParams['by_name'][$j]))
{
$isFound = true;
}
}
elseif ($arHeaders[$extractedCounter]['stored_filename'] == $arParams['by_name'][$j])
{
//check filename
$isFound = true;
}
}
}
else
{
if ((isset($arParams['by_preg'])) && ($arParams['by_preg'] != ""))
{
if (preg_match($arParams['by_preg'], $arHeaders[$extractedCounter]['stored_filename']))
{
$isFound = true;
}
}
else
{
if ((isset($arParams['by_index'])) && is_array($arParams['by_index']))
{
//index rule: if index is in the list
for ($j = $j_start, $n = count($arParams['by_index']); $j < $n && !$isFound; $j++)
{
if (($i >= $arParams['by_index'][$j]['start'])
&& ($i <= $arParams['by_index'][$j]['end']))
{
$isFound = true;
}
if ($i >= $arParams['by_index'][$j]['end'])
{
$j_start = $j + 1;
}
if ($arParams['by_index'][$j]['start'] > $i)
{
break;
}
}
}
}
}
//delete?
if ($isFound)
{
unset($arHeaders[$extractedCounter]);
}
else
{
$extractedCounter++;
}
}
//if something should be deleted
if ($extractedCounter > 0)
{
//create tmp file
$zipname_tmp = GetDirPath($this->zipname) . uniqid('ziparc') . '.tmp';
//create tmp zip archive
$tmpzip = new CZip($zipname_tmp);
if (($res = $tmpzip->_openFile('wb')) != 1)
{
$this->_closeFile();
return $res;
}
//check which file should be kept
for ($i = 0; $i < sizeof($arHeaders); $i++)
{
//calculate the position of the header
@rewind($this->zipfile);
if (@fseek($this->zipfile, $arHeaders[$i]['offset']))
{
$this->_closeFile();
$tmpzip->_closeFile();
@unlink($this->io->GetPhysicalName($zipname_tmp));
$this->_errorLog("ERR_INVALID_ARCHIVE_ZIP", GetMessage("MAIN_ZIP_ERR_INVALID_ARCHIVE_ZIP"));
return $this->arErrors;
}
if (($res = $this->_readFileHeader($arHeaders[$i])) != 1)
{
$this->_closeFile();
$tmpzip->_closeFile();
@unlink($this->io->GetPhysicalName($zipname_tmp));
return $res;
}
//writing file header
$res = $tmpzip->_writeFileHeader($arHeaders[$i]);
if ($res != 1)
{
$this->_closeFile();
$tmpzip->_closeFile();
@unlink($this->io->GetPhysicalName($zipname_tmp));
return $res;
}
//reading/writing data block
$res = $this->_copyBlocks($this->zipfile, $tmpzip->zipfile, $arHeaders[$i]['compressed_size']);
if ($res != 1)
{
$this->_closeFile();
$tmpzip->_closeFile();
@unlink($this->io->GetPhysicalName($zipname_tmp));
return $res;
}
}
//save central dir offset
$offset = @ftell($tmpzip->zipfile);
//re-write central dir files header
for ($i = 0; $i < sizeof($arHeaders); $i++)
{
$res = $tmpzip->_writeCentralFileHeader($arHeaders[$i]);
if ($res != 1)
{
$tmpzip->_closeFile();
$this->_closeFile();
@unlink($this->io->GetPhysicalName($zipname_tmp));
return $res;
}
//convert header to the 'usable' format
$tmpzip->_convertHeader2FileInfo($arHeaders[$i], $arResultList[$i]);
}
$zip_comment = '';
$size = @ftell($tmpzip->zipfile) - $offset;
$res = $tmpzip->_writeCentralHeader(sizeof($arHeaders), $size, $offset, $zip_comment);
if ($res != 1)
{
unset($arHeaders);
$tmpzip->_closeFile();
$this->_closeFile();
@unlink($this->io->GetPhysicalName($zipname_tmp));
return $res;
}
$tmpzip->_closeFile();
$this->_closeFile();
//deleting zip file (result should be checked)
@unlink($this->io->GetPhysicalName($this->zipname));
//result should be checked
$this->_renameTmpFile($zipname_tmp, $this->zipname);
unset($tmpzip);
}
return $res;
}