use new Zip helper

master
Jean-Christian Paul Denis 2023-03-18 20:05:11 +01:00
parent 0f57f7754d
commit 8c0ee39e2a
Signed by: JcDenis
GPG Key ID: 1B5B8C5B90B6C951
2 changed files with 132 additions and 121 deletions

View File

@ -24,7 +24,6 @@ use Dotclear\Plugin\improve\Action;
use form; use form;
use path; use path;
use files; use files;
use fileZip;
/** /**
* Improve action module zip * Improve action module zip
@ -65,6 +64,8 @@ class zip extends action
protected function init(): bool protected function init(): bool
{ {
require_once implode(DIRECTORY_SEPARATOR, [__DIR__, 'zip', 'Zip.php']);
$this->setProperties([ $this->setProperties([
'id' => 'zip', 'id' => 'zip',
'name' => __('Zip module'), 'name' => __('Zip module'),
@ -162,7 +163,7 @@ class zip extends action
); );
$this->setSuccess(sprintf(__('Prepare excluded files "%s"'), implode(', ', $exclude))); $this->setSuccess(sprintf(__('Prepare excluded files "%s"'), implode(', ', $exclude)));
if (!empty($this->getSetting('pack_nocomment'))) { if (!empty($this->getSetting('pack_nocomment'))) {
zipFileZip::$remove_comment = true; zip\Zip::$remove_comment = true;
$this->setSuccess(__('Prepare comment removal')); $this->setSuccess(__('Prepare comment removal'));
} }
if (!empty($this->getSetting('pack_filename'))) { if (!empty($this->getSetting('pack_filename'))) {
@ -204,8 +205,7 @@ class zip extends action
return; return;
} }
@set_time_limit(300); @set_time_limit(300);
$fp = fopen($path, 'wb'); $zip = new zip\Zip($path);
$zip = new zipFileZip($fp);
foreach ($exclude as $e) { foreach ($exclude as $e) {
$e = '#(^|/)(' . str_replace( $e = '#(^|/)(' . str_replace(
['.', '*'], ['.', '*'],
@ -219,126 +219,9 @@ class zip extends action
$this->module['id'], $this->module['id'],
true true
); );
$zip->write();
$zip->close(); $zip->close();
unset($zip); unset($zip);
$this->setSuccess(sprintf(__('Zip module into "%s"'), $path)); $this->setSuccess(sprintf(__('Zip module into "%s"'), $path));
} }
} }
class zipFileZip extends fileZip
{
/** @var boolean Should remove comments from files */
public static $remove_comment = false;
/**
* Replace clearbrick fileZip::writeFile
*
* @param string $name Name
* @param string $file File
* @param int $size Size
* @param int $mtime Mtime
*
* @return void
*/
protected function writeFile($name, $file, $size, $mtime)
{
if (!isset($this->entries[$name])) {
return;
}
$size = filesize($file);
$this->memoryAllocate($size * 3);
$content = (string) file_get_contents($file);
if (self::$remove_comment && substr($file, -4) == '.php') {
$content = self::removePHPComment($content);
}
$unc_len = strlen($content);
$crc = crc32($content);
$zdata = (string) gzdeflate($content);
$c_len = strlen($zdata);
unset($content);
$mdate = $this->makeDate($mtime);
$mtime = $this->makeTime($mtime);
# Data descriptor
$data_desc = "\x50\x4b\x03\x04" .
"\x14\x00" . # ver needed to extract
"\x00\x00" . # gen purpose bit flag
"\x08\x00" . # compression method
pack('v', $mtime) . # last mod time
pack('v', $mdate) . # last mod date
pack('V', $crc) . # crc32
pack('V', $c_len) . # compressed filesize
pack('V', $unc_len) . # uncompressed filesize
pack('v', strlen($name)) . # length of filename
pack('v', 0) . # extra field length
$name . # end of "local file header" segment
$zdata . # "file data" segment
pack('V', $crc) . # crc32
pack('V', $c_len) . # compressed filesize
pack('V', $unc_len); # uncompressed filesize
fwrite($this->fp, $data_desc);
unset($zdata);
$new_offset = $this->old_offset + strlen($data_desc);
# Add to central directory record
$cdrec = "\x50\x4b\x01\x02" .
"\x00\x00" . # version made by
"\x14\x00" . # version needed to extract
"\x00\x00" . # gen purpose bit flag
"\x08\x00" . # compression method
pack('v', $mtime) . # last mod time
pack('v', $mdate) . # last mod date
pack('V', $crc) . # crc32
pack('V', $c_len) . # compressed filesize
pack('V', $unc_len) . # uncompressed filesize
pack('v', strlen($name)) . # length of filename
pack('v', 0) . # extra field length
pack('v', 0) . # file comment length
pack('v', 0) . # disk number start
pack('v', 0) . # internal file attributes
pack('V', 32) . # external file attributes - 'archive' bit set
pack('V', $this->old_offset) . # relative offset of local header
$name;
$this->old_offset = $new_offset;
$this->ctrl_dir[] = $cdrec;
}
protected static function removePHPComment(string $content): string
{
$comment = [T_COMMENT];
if (defined('T_DOC_COMMENT')) {
$comment[] = T_DOC_COMMENT; // PHP 5
}
if (defined('T_ML_COMMENT')) {
$comment[] = T_ML_COMMENT; // PHP 4
}
$newStr = '';
$tokens = token_get_all($content);
foreach ($tokens as $token) {
if (is_array($token)) {
if (in_array($token[0], $comment)) {
//$newStr .= "\n";
} else {
$newStr .= $token[1];
}
} else {
$newStr .= $token;
}
}
return $newStr;
}
}

View File

@ -0,0 +1,128 @@
<?php
/**
* @brief improve, a plugin for Dotclear 2
*
* @package Dotclear
* @subpackage Plugin
*
* @author Jean-Christian Denis and contributors
*
* @copyright Jean-Christian Denis
* @copyright GPL-2.0 https://www.gnu.org/licenses/gpl-2.0.html
*/
declare(strict_types=1);
namespace Dotclear\Plugin\improve\Module\zip;
class Zip extends \Dotclear\Helper\File\Zip\Zip
{
/** @var boolean Should remove comments from files */
public static $remove_comment = false;
/**
* Replace helper Zip::writeFile
*
* @param string $name The name
* @param string $file The file
* @param int|null $mtime The mtime
*/
protected function writeFile(string $name, string $file, ?int $mtime)
{
if (!isset($this->entries[$name])) {
return;
}
$size = filesize($file);
$this->memoryAllocate($size * 3);
$content = (string) file_get_contents($file);
if (self::$remove_comment && substr($file, -4) == '.php') {
$content = self::removePHPComment($content);
}
$unc_len = strlen($content);
$crc = crc32($content);
$zdata = (string) gzdeflate($content);
$c_len = strlen($zdata);
unset($content);
$mdate = $this->makeDate($mtime);
$mtime = $this->makeTime($mtime);
# Data descriptor
$data_desc = "\x50\x4b\x03\x04" .
"\x14\x00" . # ver needed to extract
"\x00\x00" . # gen purpose bit flag
"\x08\x00" . # compression method
pack('v', $mtime) . # last mod time
pack('v', $mdate) . # last mod date
pack('V', $crc) . # crc32
pack('V', $c_len) . # compressed filesize
pack('V', $unc_len) . # uncompressed filesize
pack('v', strlen($name)) . # length of filename
pack('v', 0) . # extra field length
$name . # end of "local file header" segment
$zdata . # "file data" segment
pack('V', $crc) . # crc32
pack('V', $c_len) . # compressed filesize
pack('V', $unc_len); # uncompressed filesize
fwrite($this->fp, $data_desc);
unset($zdata);
$new_offset = $this->old_offset + strlen($data_desc);
# Add to central directory record
$cdrec = "\x50\x4b\x01\x02" .
"\x00\x00" . # version made by
"\x14\x00" . # version needed to extract
"\x00\x00" . # gen purpose bit flag
"\x08\x00" . # compression method
pack('v', $mtime) . # last mod time
pack('v', $mdate) . # last mod date
pack('V', $crc) . # crc32
pack('V', $c_len) . # compressed filesize
pack('V', $unc_len) . # uncompressed filesize
pack('v', strlen($name)) . # length of filename
pack('v', 0) . # extra field length
pack('v', 0) . # file comment length
pack('v', 0) . # disk number start
pack('v', 0) . # internal file attributes
pack('V', 32) . # external file attributes - 'archive' bit set
pack('V', $this->old_offset) . # relative offset of local header
$name;
$this->old_offset = $new_offset;
$this->ctrl_dir[] = $cdrec;
}
protected static function removePHPComment(string $content): string
{
$comment = [T_COMMENT];
if (defined('T_DOC_COMMENT')) {
$comment[] = T_DOC_COMMENT; // PHP 5
}
if (defined('T_ML_COMMENT')) {
$comment[] = T_ML_COMMENT; // PHP 4
}
$newStr = '';
$tokens = token_get_all($content);
foreach ($tokens as $token) {
if (is_array($token)) {
if (in_array($token[0], $comment)) {
//$newStr .= "\n";
} else {
$newStr .= $token[1];
}
} else {
$newStr .= $token;
}
}
return $newStr;
}
}