run php cs fix

This commit is contained in:
Sebijk 2022-02-21 21:04:55 +01:00
parent 6a8c9a281f
commit cb7b5bdadc
4 changed files with 1496 additions and 1473 deletions

View file

@ -19,420 +19,426 @@
* *
*/ */
if(!defined('B1GMAIL_INIT')) if (!defined('B1GMAIL_INIT')) {
die('Directly calling this file is not supported'); die('Directly calling this file is not supported');
}
if(!class_exists('BMHTTP')) if (!class_exists('BMHTTP')) {
include(B1GMAIL_DIR . 'serverlib/http.class.php'); include B1GMAIL_DIR.'serverlib/http.class.php';
}
/** /**
* sms class * sms class.
*/ */
class BMSMS class BMSMS
{ {
var $_userID; private $_userID;
var $_userObject; private $_userObject;
/** /**
* constructor * constructor.
* *
* @param int $userID User ID * @param int $userID User ID
* @param BMUser $userObject User object * @param BMUser $userObject User object
* @return BMSMS *
*/ * @return BMSMS
function __construct($userID, &$userObject) */
{ public function __construct($userID, &$userObject)
$this->_userID = (int)$userID; {
$this->_userObject = &$userObject; $this->_userID = (int) $userID;
} $this->_userObject = &$userObject;
}
/** /**
* get outbox * get outbox.
* *
* @return array * @return array
*/ */
function GetOutbox($sortColumn = 'id', $sortOrder = 'DESC') public function GetOutbox($sortColumn = 'id', $sortOrder = 'DESC')
{ {
global $db; global $db;
$result = array(); $result = [];
$res = $db->Query('SELECT id,`from`,`to`,`text`,price,`date` FROM {pre}smsend WHERE isSMS=1 AND user=? AND deleted=0 ORDER BY `' . $sortColumn . '` ' . $sortOrder . ' LIMIT 15', $res = $db->Query('SELECT id,`from`,`to`,`text`,price,`date` FROM {pre}smsend WHERE isSMS=1 AND user=? AND deleted=0 ORDER BY `'.$sortColumn.'` '.$sortOrder.' LIMIT 15',
$this->_userID); $this->_userID);
while($row = $res->FetchArray(MYSQLI_ASSOC)) while ($row = $res->FetchArray(MYSQLI_ASSOC)) {
$result[$row['id']] = $row; $result[$row['id']] = $row;
$res->Free(); }
$res->Free();
return($result); return $result;
} }
/** /**
* delete sms outbox entry * delete sms outbox entry.
* *
* @param int $id ID * @param int $id ID
*/ */
function DeleteOutboxEntry($id) public function DeleteOutboxEntry($id)
{ {
global $db; global $db;
$db->Query('UPDATE {pre}smsend SET `deleted`=1,`from`=?,`to`=?,`text`=? WHERE id=? AND user=?', $db->Query('UPDATE {pre}smsend SET `deleted`=1,`from`=?,`to`=?,`text`=? WHERE id=? AND user=?',
'', '', '', '', '', '',
$id, $this->_userID); $id, $this->_userID);
return($db->AffectedRows() == 1);
}
/** return $db->AffectedRows() == 1;
* check if $no conforms $pre-list }
*
* @param string $no
* @param string $pre
* @return bool
*/
function PreOK($no, $pre)
{
if(trim($pre) != '')
{
$ok = false;
$entries = explode(':', $pre);
foreach($entries as $entry)
{
$entry = str_replace('+', '00', preg_replace('/[^0-9]/', '', $entry));
if(substr($no, 0, strlen($entry)) == $entry)
{
$ok = true;
break;
}
}
}
else
$ok = true;
return($ok); /**
} * check if $no conforms $pre-list.
*
* @param string $no
* @param string $pre
*
* @return bool
*/
public function PreOK($no, $pre)
{
if (trim($pre) != '') {
$ok = false;
$entries = explode(':', $pre);
foreach ($entries as $entry) {
$entry = str_replace('+', '00', preg_replace('/[^0-9]/', '', $entry));
if (substr($no, 0, strlen($entry)) == $entry) {
$ok = true;
break;
}
}
} else {
$ok = true;
}
/** return $ok;
* get available SMS types }
*
* @return array
*/
function GetTypes()
{
global $db;
if(is_object($this->_userObject)) /**
{ * get available SMS types.
$group = $this->_userObject->GetGroup(); *
$groupRow = $group->Fetch(); * @return array
} */
else public function GetTypes()
$groupRow = array('sms_sig' => ''); {
global $db;
$result = array(); if (is_object($this->_userObject)) {
$res = $db->Query('SELECT id,titel,typ,std,price,gateway,flags,maxlength FROM {pre}smstypen ORDER BY titel ASC'); $group = $this->_userObject->GetGroup();
while($row = $res->FetchArray(MYSQLI_ASSOC)) $groupRow = $group->Fetch();
$result[$row['id']] = array( } else {
'id' => $row['id'], $groupRow = ['sms_sig' => ''];
'title' => $row['titel'], }
'type' => $row['typ'],
'default' => $row['std'] == 1,
'price' => $row['price'],
'gateway' => $row['gateway'],
'flags' => $row['flags'],
'maxlength' => $row['maxlength'] - strlen($groupRow['sms_sig'])
);
$res->Free();
return($result); $result = [];
} $res = $db->Query('SELECT id,titel,typ,std,price,gateway,flags,maxlength FROM {pre}smstypen ORDER BY titel ASC');
while ($row = $res->FetchArray(MYSQLI_ASSOC)) {
$result[$row['id']] = [
'id' => $row['id'],
'title' => $row['titel'],
'type' => $row['typ'],
'default' => $row['std'] == 1,
'price' => $row['price'],
'gateway' => $row['gateway'],
'flags' => $row['flags'],
'maxlength' => $row['maxlength'] - strlen($groupRow['sms_sig']),
];
}
$res->Free();
/** return $result;
* get max SMS chars for user }
*
* @return int
*/
function GetMaxChars($typeID = 0)
{
global $db;
if(is_object($this->_userObject)) /**
{ * get max SMS chars for user.
$group = $this->_userObject->GetGroup(); *
$groupRow = $group->Fetch(); * @return int
} */
else public function GetMaxChars($typeID = 0)
$groupRow = array('sms_sig' => ''); {
global $db;
$maxChars = 160; if (is_object($this->_userObject)) {
$group = $this->_userObject->GetGroup();
$groupRow = $group->Fetch();
} else {
$groupRow = ['sms_sig' => ''];
}
if($typeID > 0) $maxChars = 160;
{
$res = $db->Query('SELECT maxlength FROM {pre}smstypen WHERE id=?', $typeID);
while($row = $res->FetchArray(MYSQLI_ASSOC))
$maxChars = $row['maxlength'];
$res->Free();
}
return($maxChars - strlen($groupRow['sms_sig'])); if ($typeID > 0) {
} $res = $db->Query('SELECT maxlength FROM {pre}smstypen WHERE id=?', $typeID);
while ($row = $res->FetchArray(MYSQLI_ASSOC)) {
$maxChars = $row['maxlength'];
}
$res->Free();
}
/** return $maxChars - strlen($groupRow['sms_sig']);
* get default gateway or gateway specified by ID }
*
* @param int $id ID (0 = default gateway)
* @return array
*/
function GetGateway($id = 0)
{
global $bm_prefs, $db;
if($id == 0) /**
$id = $bm_prefs['sms_gateway']; * get default gateway or gateway specified by ID.
*
* @param int $id ID (0 = default gateway)
*
* @return array
*/
public function GetGateway($id = 0)
{
global $bm_prefs, $db;
$res = $db->Query('SELECT id,titel,getstring,success,`user`,`pass` FROM {pre}smsgateways WHERE id=?', if ($id == 0) {
$id); $id = $bm_prefs['sms_gateway'];
if($res->RowCount() == 1) }
{
$row = $res->FetchArray(MYSQLI_ASSOC);
$res->Free();
return(array( $res = $db->Query('SELECT id,titel,getstring,success,`user`,`pass` FROM {pre}smsgateways WHERE id=?',
'id' => $row['id'], $id);
'title' => $row['titel'], if ($res->RowCount() == 1) {
'getstring' => $row['getstring'], $row = $res->FetchArray(MYSQLI_ASSOC);
'success' => $row['success'], $res->Free();
'user' => $row['user'],
'pass' => $row['pass']
));
}
return(false);
}
/** return [
* send SMS 'id' => $row['id'],
* 'title' => $row['titel'],
* @param string $from From 'getstring' => $row['getstring'],
* @param string $to To 'success' => $row['success'],
* @param string $text Text 'user' => $row['user'],
* @param int $type Type ID (0 = default type) 'pass' => $row['pass'],
* @param bool $charge Charge user account? ];
* @param bool $putToOutbox Put SMS to outbox? }
* @param int $outboxID ID of outbox entry, if already available
* @return bool
*/
function Send($from, $to, $text, $type = 0, $charge = true, $putToOutbox = true, $outboxID = 0)
{
global $bm_prefs, $db, $lang_user;
// module handler return false;
ModuleFunction('OnSendSMS', array(&$text, &$type, &$from, &$to, &$this->_userObject)); }
// get type and type list /**
$types = $this->GetTypes(); * send SMS.
if($type == 0) *
{ * @param string $from From
foreach($types as $typeID=>$typeInfo) * @param string $to To
if($typeInfo['default']) * @param string $text Text
$type = $typeID; * @param int $type Type ID (0 = default type)
if($type == 0) * @param bool $charge Charge user account?
{ * @param bool $putToOutbox Put SMS to outbox?
PutLog(sprintf('Default SMS type <%d> not found while trying to send SMS from <%s> to <%s> (userID: %d)', * @param int $outboxID ID of outbox entry, if already available
$type, *
$from, * @return bool
$to, */
$this->_userID), public function Send($from, $to, $text, $type = 0, $charge = true, $putToOutbox = true, $outboxID = 0)
PRIO_WARNING, {
__FILE__, global $bm_prefs, $db, $lang_user;
__LINE__);
return(false);
}
}
if(isset($types[$type]))
$type = $types[$type];
else
{
PutLog(sprintf('SMS type <%d> not found while trying to send SMS from <%s> to <%s> (userID: %d)',
$type,
$from,
$to,
$this->_userID),
PRIO_WARNING,
__FILE__,
__LINE__);
return(false);
}
// crop text // module handler
if(_strlen($text) > $this->GetMaxChars($type['id'])) ModuleFunction('OnSendSMS', [&$text, &$type, &$from, &$to, &$this->_userObject]);
$text = _substr($text, 0, $this->GetMaxChars($type['id']));
// check account balance // get type and type list
if($charge) $types = $this->GetTypes();
{ if ($type == 0) {
$balance = $this->_userObject->GetBalance(); foreach ($types as $typeID => $typeInfo) {
if($balance < $type['price']) if ($typeInfo['default']) {
{ $type = $typeID;
PutLog(sprintf('Failed to send SMS from <%s> to <%s>: Not enough credits (userID: %d)', }
$from, }
$to, if ($type == 0) {
$this->_userID), PutLog(sprintf('Default SMS type <%d> not found while trying to send SMS from <%s> to <%s> (userID: %d)',
PRIO_NOTE, $type,
__FILE__, $from,
__LINE__); $to,
return(false); $this->_userID),
} PRIO_WARNING,
} __FILE__,
__LINE__);
// get gateway info return false;
$gateway = $this->GetGateway($type['gateway']); }
if(!$gateway) }
{ if (isset($types[$type])) {
PutLog(sprintf('Gateway <%d> not found while trying to send SMS with type <%d> from <%s> to <%s> (userID: %d)', $type = $types[$type];
$type['gateway'], } else {
$type['id'], PutLog(sprintf('SMS type <%d> not found while trying to send SMS from <%s> to <%s> (userID: %d)',
$from, $type,
$to, $from,
$this->_userID), $to,
PRIO_WARNING, $this->_userID),
__FILE__, PRIO_WARNING,
__LINE__); __FILE__,
return(false); __LINE__);
}
// prepare formatted numbers return false;
$fromPlus = preg_replace('/^00/', '+', $from); }
$toPlus = preg_replace('/^00/', '+', $to);
// build GET string // crop text
$getString = $gateway['getstring']; if (_strlen($text) > $this->GetMaxChars($type['id'])) {
$getString = str_replace('%%user%%', $text = _substr($text, 0, $this->GetMaxChars($type['id']));
_urlencode($gateway['user']), }
$getString);
$getString = str_replace('%%passwort%%',
_urlencode($gateway['pass']),
$getString);
$getString = str_replace('%%from%%',
urlencode(CharsetDecode($from, false, 'ISO-8859-1')),
$getString);
$getString = str_replace('%%fromPlus%%',
urlencode(CharsetDecode($fromPlus, false, 'ISO-8859-1')),
$getString);
$getString = str_replace('%%from_utf8%%',
urlencode(CharsetDecode($from, false, 'UTF-8')),
$getString);
$getString = str_replace('%%to%%',
_urlencode($to),
$getString);
$getString = str_replace('%%toPlus%%',
_urlencode($toPlus),
$getString);
$getString = str_replace('%%msg%%',
urlencode(CharsetDecode($text, false, 'ISO-8859-1')),
$getString);
$getString = str_replace('%%msg_utf8%%',
urlencode(CharsetDecode($text, false, 'UTF-8')),
$getString);
if($this->_userObject)
{
$getString = str_replace('%%usermail%%',
_urlencode($this->_userObject->_row['email']),
$getString);
$getString = str_replace('%%userid%%',
_urlencode($this->_userObject->_id),
$getString);
}
$getString = str_replace('%%typ%%',
_urlencode($type['type']),
$getString);
// request! // check account balance
$http = _new('BMHTTP', array($getString)); if ($charge) {
$result = $http->DownloadToString(); $balance = $this->_userObject->GetBalance();
$success = (trim($gateway['success']) == '' && trim($result) == '') if ($balance < $type['price']) {
|| (strpos(strtolower($result), strtolower($gateway['success'])) !== false); PutLog(sprintf('Failed to send SMS from <%s> to <%s>: Not enough credits (userID: %d)',
$from,
$to,
$this->_userID),
PRIO_NOTE,
__FILE__,
__LINE__);
// log return false;
PutLog(sprintf('SMS success: %d; expected result: <%s>; gateway result: <%s> (userID: %d)', }
$success, }
$gateway['success'],
$result,
$this->_userID),
PRIO_DEBUG,
__FILE__,
__LINE__);
// ok? // get gateway info
if($success) $gateway = $this->GetGateway($type['gateway']);
{ if (!$gateway) {
// status ID? PutLog(sprintf('Gateway <%d> not found while trying to send SMS with type <%d> from <%s> to <%s> (userID: %d)',
if(preg_match('/Status\:([0-9]*)/', $result, $reg) && is_array($reg) && isset($reg[1])) $type['gateway'],
$statusID = $reg[1]; $type['id'],
else $from,
$statusID = -1; $to,
$this->_userID),
PRIO_WARNING,
__FILE__,
__LINE__);
// stats return false;
Add2Stat('sms'); }
// charge, if requested // prepare formatted numbers
if($charge) $fromPlus = preg_replace('/^00/', '+', $from);
$outboxID = $this->_userObject->Debit($type['price']*-1, $lang_user['tx_sms']); $toPlus = preg_replace('/^00/', '+', $to);
// put to outbox? // build GET string
if($putToOutbox) $getString = $gateway['getstring'];
if($outboxID == 0) $getString = str_replace('%%user%%',
{ _urlencode($gateway['user']),
$db->Query('INSERT INTO {pre}smsend(user,monat,price,isSMS,`from`,`to`,`text`,statusid,`date`) VALUES(?,?,?,?,?,?,?,?,?)', $getString);
$this->_userID, $getString = str_replace('%%passwort%%',
(int)date('mY'), _urlencode($gateway['pass']),
0, $getString);
1, $getString = str_replace('%%from%%',
$from, urlencode(CharsetDecode($from, false, 'ISO-8859-1')),
$to, $getString);
$text, $getString = str_replace('%%fromPlus%%',
$statusID, urlencode(CharsetDecode($fromPlus, false, 'ISO-8859-1')),
time()); $getString);
$outboxID = $db->InsertId(); $getString = str_replace('%%from_utf8%%',
} urlencode(CharsetDecode($from, false, 'UTF-8')),
else $getString);
$db->Query('UPDATE {pre}smsend SET isSMS=?,`from`=?,`to`=?,`text`=?,statusid=?,`date`=? WHERE id=? AND user=?', $getString = str_replace('%%to%%',
1, _urlencode($to),
$from, $getString);
$to, $getString = str_replace('%%toPlus%%',
$text, _urlencode($toPlus),
$statusID, $getString);
time(), $getString = str_replace('%%msg%%',
$outboxID, urlencode(CharsetDecode($text, false, 'ISO-8859-1')),
$this->_userID); $getString);
$getString = str_replace('%%msg_utf8%%',
urlencode(CharsetDecode($text, false, 'UTF-8')),
$getString);
if ($this->_userObject) {
$getString = str_replace('%%usermail%%',
_urlencode($this->_userObject->_row['email']),
$getString);
$getString = str_replace('%%userid%%',
_urlencode($this->_userObject->_id),
$getString);
}
$getString = str_replace('%%typ%%',
_urlencode($type['type']),
$getString);
// module handler // request!
ModuleFunction('AfterSendSMS', array(true, $result, $outboxID)); $http = _new('BMHTTP', [$getString]);
$result = $http->DownloadToString();
$success = (trim($gateway['success']) == '' && trim($result) == '')
|| (strpos(strtolower($result), strtolower($gateway['success'])) !== false);
// log // log
PutLog(sprintf('Sent SMS from <%s> to <%s> (type: %d; statusID: %d; charged: %d; userID: %d)', PutLog(sprintf('SMS success: %d; expected result: <%s>; gateway result: <%s> (userID: %d)',
$from, $success,
$to, $gateway['success'],
$type['id'], $result,
$statusID, $this->_userID),
$charge ? $type['price'] : 0, PRIO_DEBUG,
$this->_userID), __FILE__,
PRIO_NOTE, __LINE__);
__FILE__,
__LINE__);
return(true);
}
else
{
// module handler
ModuleFunction('AfterSendSMS', array(false, $result, $outboxID));
// log // ok?
PutLog(sprintf('Failed to send SMS from <%s> to <%s> (type: %d; charged: 0; userID: %d)', if ($success) {
$from, // status ID?
$to, if (preg_match('/Status\:([0-9]*)/', $result, $reg) && is_array($reg) && isset($reg[1])) {
$type['id'], $statusID = $reg[1];
$this->_userID), } else {
PRIO_NOTE, $statusID = -1;
__FILE__, }
__LINE__);
return(false); // stats
} Add2Stat('sms');
}
// charge, if requested
if ($charge) {
$outboxID = $this->_userObject->Debit($type['price'] * -1, $lang_user['tx_sms']);
}
// put to outbox?
if ($putToOutbox) {
if ($outboxID == 0) {
$db->Query('INSERT INTO {pre}smsend(user,monat,price,isSMS,`from`,`to`,`text`,statusid,`date`) VALUES(?,?,?,?,?,?,?,?,?)',
$this->_userID,
(int) date('mY'),
0,
1,
$from,
$to,
$text,
$statusID,
time());
$outboxID = $db->InsertId();
} else {
$db->Query('UPDATE {pre}smsend SET isSMS=?,`from`=?,`to`=?,`text`=?,statusid=?,`date`=? WHERE id=? AND user=?',
1,
$from,
$to,
$text,
$statusID,
time(),
$outboxID,
$this->_userID);
}
}
// module handler
ModuleFunction('AfterSendSMS', [true, $result, $outboxID]);
// log
PutLog(sprintf('Sent SMS from <%s> to <%s> (type: %d; statusID: %d; charged: %d; userID: %d)',
$from,
$to,
$type['id'],
$statusID,
$charge ? $type['price'] : 0,
$this->_userID),
PRIO_NOTE,
__FILE__,
__LINE__);
return true;
} else {
// module handler
ModuleFunction('AfterSendSMS', [false, $result, $outboxID]);
// log
PutLog(sprintf('Failed to send SMS from <%s> to <%s> (type: %d; charged: 0; userID: %d)',
$from,
$to,
$type['id'],
$this->_userID),
PRIO_NOTE,
__FILE__,
__LINE__);
return false;
}
}
} }

File diff suppressed because it is too large Load diff

View file

@ -19,240 +19,243 @@
* *
*/ */
if(!defined('B1GMAIL_INIT')) if (!defined('B1GMAIL_INIT')) {
die('Directly calling this file is not supported'); die('Directly calling this file is not supported');
}
/** /**
* Basic UnZIP class * Basic UnZIP class.
*
*/ */
class BMUnZIP class BMUnZIP
{ {
var $_fp; private $_fp;
var $_centralDirStruct; private $_centralDirStruct;
/** /**
* constructor * constructor.
* *
* @param resource $fp Input file stream * @param resource $fp Input file stream
* @return BMUnZIP *
*/ * @return BMUnZIP
function __construct($fp) */
{ public function __construct($fp)
$this->_fp = $fp; {
$this->_readCentralDirStruct(); $this->_fp = $fp;
} $this->_readCentralDirStruct();
}
/** /**
* get ZIP file directory listing * get ZIP file directory listing.
* *
* @return array * @return array
*/ */
function GetFileList() public function GetFileList()
{ {
return($this->_centralDirStruct); return $this->_centralDirStruct;
} }
/** /**
* get ZIP file directory listing prepared for tree display * get ZIP file directory listing prepared for tree display.
* *
* @return array * @return array
*/ */
function GetFileTree() public function GetFileTree()
{ {
$tree = array(); $tree = [];
$folderNoCounter = count($this->_centralDirStruct); $folderNoCounter = count($this->_centralDirStruct);
// add files // add files
foreach($this->_centralDirStruct as $fileNo=>$file) foreach ($this->_centralDirStruct as $fileNo => $file) {
{ $file['parentID'] = -2;
$file['parentID'] = -2; $file['type'] = 'file';
$file['type'] = 'file'; $file['fileNo'] = $fileNo;
$file['fileNo'] = $fileNo; $file['baseName'] = basename($file['fileName']);
$file['baseName'] = basename($file['fileName']);
$tree[] = $file; $tree[] = $file;
} }
// add folders // add folders
$again = true; $again = true;
while($again) while ($again) {
{ $again = false;
$again = false;
foreach($tree as $id=>$item) foreach ($tree as $id => $item) {
{ if ($item['parentID'] != -2) {
if($item['parentID'] != -2) continue;
continue; }
$parentFolderName = dirname($item['fileName']); $parentFolderName = dirname($item['fileName']);
if($parentFolderName != '.' && $parentFolderName != '') if ($parentFolderName != '.' && $parentFolderName != '') {
{ $parentID = -2;
$parentID = -2;
foreach($tree as $id2=>$item2) foreach ($tree as $id2 => $item2) {
{ if ($item2['type'] == 'folder' && $item2['fileName'] == $parentFolderName) {
if($item2['type'] == 'folder' && $item2['fileName'] == $parentFolderName) $parentID = $item2['fileNo'];
{ break;
$parentID = $item2['fileNo']; }
break; }
}
}
if($parentID == -2) if ($parentID == -2) {
{ $folderNo = $folderNoCounter++;
$folderNo = $folderNoCounter++; $tree[] = ['type' => 'folder',
$tree[] = array('type' => 'folder', 'fileName' => $parentFolderName,
'fileName' => $parentFolderName, 'baseName' => basename($parentFolderName),
'baseName' => basename($parentFolderName), 'fileNo' => $folderNo,
'fileNo' => $folderNo, 'parentID' => -2, ];
'parentID' => -2); $parentID = $folderNo;
$parentID = $folderNo; $again = true;
$again = true; }
}
$tree[$id]['parentID'] = $parentID; $tree[$id]['parentID'] = $parentID;
} }
} }
} }
return($tree); return $tree;
} }
/** /**
* extract a file by file no * extract a file by file no.
* *
* @param int $fileNo File no (from GetFileList() array) * @param int $fileNo File no (from GetFileList() array)
* @param resource $fp Output file stream * @param resource $fp Output file stream
* @return bool *
*/ * @return bool
function ExtractFile($fileNo, $fp = false, $sizeLimit = -1) */
{ public function ExtractFile($fileNo, $fp = false, $sizeLimit = -1)
if(!isset($this->_centralDirStruct[$fileNo])) {
return(false); if (!isset($this->_centralDirStruct[$fileNo])) {
return false;
}
if(!in_array($this->_centralDirStruct[$fileNo]['compressionMethod'], array(8, 12))) if (!in_array($this->_centralDirStruct[$fileNo]['compressionMethod'], [8, 12])) {
return(false); return false;
}
fseek($this->_fp, $this->_centralDirStruct[$fileNo]['relativeOffset'], SEEK_SET); fseek($this->_fp, $this->_centralDirStruct[$fileNo]['relativeOffset'], SEEK_SET);
$fileHeader = fread($this->_fp, 30); $fileHeader = fread($this->_fp, 30);
$_fileHeader = @unpack('Vsignature/vversionNeeded/vflags/vcompressionMethod/vmTime/vmDate/Vcrc32/VcompressedSize/VuncompressedSize/vfileNameLength/vextraFieldLength', $_fileHeader = @unpack('Vsignature/vversionNeeded/vflags/vcompressionMethod/vmTime/vmDate/Vcrc32/VcompressedSize/VuncompressedSize/vfileNameLength/vextraFieldLength',
$fileHeader); $fileHeader);
if(!$_fileHeader || $_fileHeader['signature'] != 0x04034b50) if (!$_fileHeader || $_fileHeader['signature'] != 0x04034b50) {
return(false); return false;
}
fseek($this->_fp, $_fileHeader['fileNameLength']+$_fileHeader['extraFieldLength'], SEEK_CUR); fseek($this->_fp, $_fileHeader['fileNameLength'] + $_fileHeader['extraFieldLength'], SEEK_CUR);
$_fileHeader = $this->_centralDirStruct[$fileNo]; $_fileHeader = $this->_centralDirStruct[$fileNo];
if($_fileHeader['compressedSize'] > 0) if ($_fileHeader['compressedSize'] > 0) {
{ $compressedData = fread($this->_fp, $_fileHeader['compressedSize']);
$compressedData = fread($this->_fp, $_fileHeader['compressedSize']); $uncompressedData = '';
$uncompressedData = '';
if($_fileHeader['compressionMethod'] == 8) if ($_fileHeader['compressionMethod'] == 8) {
{ $uncompressedData = @gzinflate($compressedData);
$uncompressedData = @gzinflate($compressedData); } elseif ($_fileHeader['compressionMethod'] == 12) {
} $uncompressedData = @bzdecompress($compressedData);
else if($_fileHeader['compressionMethod'] == 12) }
{
$uncompressedData = @bzdecompress($compressedData);
}
unset($compressedData); unset($compressedData);
if(crc32($uncompressedData) != $_fileHeader['crc32']) if (crc32($uncompressedData) != $_fileHeader['crc32']) {
return(false); return false;
}
if($fp !== false) if ($fp !== false) {
fwrite($fp, $uncompressedData, $sizeLimit != -1 ? $sizeLimit : strlen($uncompressedData)); fwrite($fp, $uncompressedData, $sizeLimit != -1 ? $sizeLimit : strlen($uncompressedData));
else } else {
echo($uncompressedData); echo $uncompressedData;
} }
else if($_fileHeader['crc32'] != 0) } elseif ($_fileHeader['crc32'] != 0) {
{ return false;
return(false); }
}
return(true); return true;
} }
/** /**
* read central dir struct from ZIP file * read central dir struct from ZIP file.
* */
*/ private function _readCentralDirStruct()
function _readCentralDirStruct() {
{ $this->_centralDirStruct = [];
$this->_centralDirStruct = array();
fseek($this->_fp, -22, SEEK_END); fseek($this->_fp, -22, SEEK_END);
$endOfCDS = fread($this->_fp, 22); $endOfCDS = fread($this->_fp, 22);
while(substr($endOfCDS, 0, 4) != pack('V', 0x06054b50)) while (substr($endOfCDS, 0, 4) != pack('V', 0x06054b50)) {
{ fseek($this->_fp, -1, SEEK_CUR);
fseek($this->_fp, -1, SEEK_CUR); $endOfCDS = fgetc($this->_fp).$endOfCDS;
$endOfCDS = fgetc($this->_fp) . $endOfCDS; fseek($this->_fp, -1, SEEK_CUR);
fseek($this->_fp, -1, SEEK_CUR);
if(ftell($this->_fp) < 2) if (ftell($this->_fp) < 2) {
break; break;
} }
}
if(substr($endOfCDS, 0, 4) != pack('V', 0x06054b50)) if (substr($endOfCDS, 0, 4) != pack('V', 0x06054b50)) {
{ if (DEBUG) {
if(DEBUG) trigger_error('File corrupt or not in ZIP format', E_USER_NOTICE); trigger_error('File corrupt or not in ZIP format', E_USER_NOTICE);
return; }
}
// parse endOfCDS record return;
$_endOfCDS = @unpack('Vsignature/vdiskNo/vcdsStartDiskNo/vcdsDiskEntryCount/vcdsTotalEntryCount/VcdsSize/VcdsOffset/vcommentLength', $endOfCDS); }
if(!$_endOfCDS)
{
if(DEBUG) trigger_error('File corrupt or not in ZIP format (eoCDS broken)', E_USER_NOTICE);
return;
}
// seek to CDS offset // parse endOfCDS record
fseek($this->_fp, $_endOfCDS['cdsOffset'], SEEK_SET); $_endOfCDS = @unpack('Vsignature/vdiskNo/vcdsStartDiskNo/vcdsDiskEntryCount/vcdsTotalEntryCount/VcdsSize/VcdsOffset/vcommentLength', $endOfCDS);
if (!$_endOfCDS) {
if (DEBUG) {
trigger_error('File corrupt or not in ZIP format (eoCDS broken)', E_USER_NOTICE);
}
// read CDS entries return;
for($i=0; $i<$_endOfCDS['cdsDiskEntryCount'] && !feof($this->_fp); $i++) }
{
$fileHeader = fread($this->_fp, 46);
$_fileHeader = @unpack('Vsignature/vversion/vversionNeeded/vflags/vcompressionMethod/vmTime/vmDate/Vcrc32/VcompressedSize/VuncompressedSize/vfileNameLength/vextraFieldLength/vfileCommentLength/vdiskNumberStart/vinternalAttrs/VexternalAttrs/VrelativeOffset', // seek to CDS offset
$fileHeader); fseek($this->_fp, $_endOfCDS['cdsOffset'], SEEK_SET);
if(!$_fileHeader || $_fileHeader['signature'] != 0x02014b50)
{
if(DEBUG) trigger_error('File corrupt (CDS broken)');
return;
}
$_fileHeader['cdsOffset'] = ftell($this->_fp) - strlen($fileHeader); // read CDS entries
for ($i = 0; $i < $_endOfCDS['cdsDiskEntryCount'] && !feof($this->_fp); ++$i) {
$fileHeader = fread($this->_fp, 46);
if($_fileHeader['fileNameLength'] > 0) $_fileHeader = @unpack('Vsignature/vversion/vversionNeeded/vflags/vcompressionMethod/vmTime/vmDate/Vcrc32/VcompressedSize/VuncompressedSize/vfileNameLength/vextraFieldLength/vfileCommentLength/vdiskNumberStart/vinternalAttrs/VexternalAttrs/VrelativeOffset',
$_fileHeader['fileName'] = fread($this->_fp, $_fileHeader['fileNameLength']); $fileHeader);
if($_fileHeader['extraFieldLength'] > 0) if (!$_fileHeader || $_fileHeader['signature'] != 0x02014b50) {
$_fileHeader['extraField'] = fread($this->_fp, $_fileHeader['extraFieldLength']); if (DEBUG) {
if($_fileHeader['fileCommentLength'] > 0) trigger_error('File corrupt (CDS broken)');
$_fileHeader['fileComment'] = fread($this->_fp, $_fileHeader['fileCommentLength']); }
if(substr($_fileHeader['fileName'], -1) == '/' && $_fileHeader['uncompressedSize'] == 0) return;
continue; }
$this->_centralDirStruct[] = $_fileHeader; $_fileHeader['cdsOffset'] = ftell($this->_fp) - strlen($fileHeader);
}
// sort by filename if ($_fileHeader['fileNameLength'] > 0) {
uasort($this->_centralDirStruct, array(&$this, '_sortHandler')); $_fileHeader['fileName'] = fread($this->_fp, $_fileHeader['fileNameLength']);
} }
if ($_fileHeader['extraFieldLength'] > 0) {
$_fileHeader['extraField'] = fread($this->_fp, $_fileHeader['extraFieldLength']);
}
if ($_fileHeader['fileCommentLength'] > 0) {
$_fileHeader['fileComment'] = fread($this->_fp, $_fileHeader['fileCommentLength']);
}
function _sortHandler($s1, $s2) if (substr($_fileHeader['fileName'], -1) == '/' && $_fileHeader['uncompressedSize'] == 0) {
{ continue;
return(strcmp($s1['fileName'], $s2['fileName'])); }
}
$this->_centralDirStruct[] = $_fileHeader;
}
// sort by filename
uasort($this->_centralDirStruct, [&$this, '_sortHandler']);
}
private function _sortHandler($s1, $s2)
{
return strcmp($s1['fileName'], $s2['fileName']);
}
} }

View file

@ -19,220 +19,220 @@
* *
*/ */
if(!defined('B1GMAIL_INIT')) if (!defined('B1GMAIL_INIT')) {
die('Directly calling this file is not supported'); die('Directly calling this file is not supported');
}
/** /**
* ZIP class * ZIP class.
*
*/ */
class BMZIP class BMZIP
{ {
/** /**
* b1gZIP stream (used if b1gZIP is installed) * b1gZIP stream (used if b1gZIP is installed).
* *
* @var resource * @var resource
*/ */
var $_b1gzip_stream; private $_b1gzip_stream;
/** /**
* output stream * output stream.
* *
* @var resource * @var resource
*/ */
var $_fp; private $_fp;
/** /**
* central directory structure * central directory structure.
* *
* @var array * @var array
*/ */
var $_centralDirStruct; private $_centralDirStruct;
/** /**
* constructor * constructor.
* *
* @param resource $fp Output stream * @param resource $fp Output stream
* @return BMZIP *
*/ * @return BMZIP
function __construct($fp) */
{ public function __construct($fp)
// output stream {
$this->_fp = $fp; // output stream
$this->_fp = $fp;
// use b1gZIP? // use b1gZIP?
if(function_exists('b1gzip_create') if (function_exists('b1gzip_create')
&& function_exists('b1gzip_add') && function_exists('b1gzip_add')
&& function_exists('b1gzip_final')) && function_exists('b1gzip_final')) {
{ $this->_b1gzip_stream = b1gzip_create();
$this->_b1gzip_stream = b1gzip_create(); } else {
} $this->_b1gzip_stream = false;
else $this->_centralDirStruct = [];
{ }
$this->_b1gzip_stream = false; }
$this->_centralDirStruct = array();
}
}
/** /**
* add a file to ZIP file * add a file to ZIP file.
* *
* @param string $fileName File name * @param string $fileName File name
* @param string $zipFileName File name in ZIP file * @param string $zipFileName File name in ZIP file
* @return bool *
*/ * @return bool
function AddFile($fileName, $zipFileName = false) */
{ public function AddFile($fileName, $zipFileName = false)
$fileFP = @fopen($fileName, 'rb'); {
if($fileFP) $fileFP = @fopen($fileName, 'rb');
{ if ($fileFP) {
$result = $this->AddFileByFP($fileFP, $fileName, $zipFileName); $result = $this->AddFileByFP($fileFP, $fileName, $zipFileName);
fclose($fileFP); fclose($fileFP);
return($result);
}
else
return(false);
}
/** return $result;
* add a file to ZIP file by file pointer } else {
* return false;
* @param resource $fileFP }
* @param string $fileName }
* @param string $zipFileName
* @return bool
*/
function AddFileByFP($fileFP, $fileName, $zipFileName = false)
{
if(!$zipFileName)
$zipFileName = basename($fileName);
// read file /**
fseek($fileFP, 0, SEEK_SET); * add a file to ZIP file by file pointer.
$fileData = ''; *
while(is_resource($fileFP) && !feof($fileFP)) * @param resource $fileFP
$fileData .= @fread($fileFP, 4096); * @param string $fileName
$uncompressedSize = strlen($fileData); * @param string $zipFileName
*
* @return bool
*/
public function AddFileByFP($fileFP, $fileName, $zipFileName = false)
{
if (!$zipFileName) {
$zipFileName = basename($fileName);
}
// use b1gZIP // read file
if($this->_b1gzip_stream) fseek($fileFP, 0, SEEK_SET);
{ $fileData = '';
b1gzip_add($this->_b1gzip_stream, $fileData, $zipFileName); while (is_resource($fileFP) && !feof($fileFP)) {
return(true); $fileData .= @fread($fileFP, 4096);
} }
$uncompressedSize = strlen($fileData);
// or own implementation // use b1gZIP
else if ($this->_b1gzip_stream) {
{ b1gzip_add($this->_b1gzip_stream, $fileData, $zipFileName);
// compute crc32
$crc32 = crc32($fileData);
$compressedData = gzcompress($fileData);
unset($fileData);
$compressedData = substr($compressedData, 2, -4);
$compressedSize = strlen($compressedData);
// write file header return true;
$this->_beginFile($crc32, $compressedSize, $uncompressedSize, $zipFileName); }
fwrite($this->_fp, $compressedData);
}
return(false); // or own implementation
} else {
// compute crc32
$crc32 = crc32($fileData);
$compressedData = gzcompress($fileData);
unset($fileData);
$compressedData = substr($compressedData, 2, -4);
$compressedSize = strlen($compressedData);
/** // write file header
* begin file $this->_beginFile($crc32, $compressedSize, $uncompressedSize, $zipFileName);
* fwrite($this->_fp, $compressedData);
* @param int $crc32 }
* @param int $compressedSize
* @param int $uncompressedSize
* @param string $fileName
*/
function _beginFile($crc32, $compressedSize, $uncompressedSize, $fileName)
{
// local header
$header = pack('VvvvvvVVVvv',
0x04034b50,
0x0014,
0x0,
0x0008,
(date('H') << 11) | (date('i') << 5) | round(date('s')/2, 0),
(date('Y')-1980 << 9) | (date('m') << 5) | date('d'),
$crc32,
$compressedSize,
$uncompressedSize,
strlen($fileName),
0x0);
$offset = ftell($this->_fp);
fwrite($this->_fp, $header);
fwrite($this->_fp, $fileName);
// central dir struct entry return false;
$entry = pack('VvvvvvvVVVvvvvvVV', }
0x02014b50,
0x0,
0x0014,
0x0,
0x0008,
(date('H') << 11) | (date('i') << 5) | round(date('s')/2, 0),
(date('Y')-1980 << 9) | (date('m') << 5) | date('d'),
$crc32,
$compressedSize,
$uncompressedSize,
strlen($fileName),
0x0,
0x0,
0x0,
0x0,
32,
$offset);
$entry .= $fileName;
$this->_centralDirStruct[] = $entry;
}
/** /**
* finish zip file * begin file.
* *
* @return int Size * @param int $crc32
*/ * @param int $compressedSize
function Finish() * @param int $uncompressedSize
{ * @param string $fileName
// use b1gZIP? */
if($this->_b1gzip_stream) private function _beginFile($crc32, $compressedSize, $uncompressedSize, $fileName)
{ {
$zipData = b1gzip_final($this->_b1gzip_stream); // local header
fwrite($this->_fp, $zipData); $header = pack('VvvvvvVVVvv',
fseek($this->_fp, 0, SEEK_SET); 0x04034b50,
return(strlen($zipData)); 0x0014,
} 0x0,
0x0008,
(date('H') << 11) | (date('i') << 5) | round(date('s') / 2, 0),
(date('Y') - 1980 << 9) | (date('m') << 5) | date('d'),
$crc32,
$compressedSize,
$uncompressedSize,
strlen($fileName),
0x0);
$offset = ftell($this->_fp);
fwrite($this->_fp, $header);
fwrite($this->_fp, $fileName);
// or own implementation // central dir struct entry
else $entry = pack('VvvvvvvVVVvvvvvVV',
{ 0x02014b50,
// write central dir struct 0x0,
$offset = ftell($this->_fp); 0x0014,
$dLength = 0; 0x0,
foreach($this->_centralDirStruct as $item) 0x0008,
{ (date('H') << 11) | (date('i') << 5) | round(date('s') / 2, 0),
fwrite($this->_fp, $item); (date('Y') - 1980 << 9) | (date('m') << 5) | date('d'),
$dLength += strlen($item); $crc32,
} $compressedSize,
$uncompressedSize,
strlen($fileName),
0x0,
0x0,
0x0,
0x0,
32,
$offset);
$entry .= $fileName;
$this->_centralDirStruct[] = $entry;
}
// write footer /**
$footer = pack('VvvvvVVv', * finish zip file.
0x06054b50, *
0x0, * @return int Size
0x0, */
count($this->_centralDirStruct), public function Finish()
count($this->_centralDirStruct), {
$dLength, // use b1gZIP?
$offset, if ($this->_b1gzip_stream) {
0x0); $zipData = b1gzip_final($this->_b1gzip_stream);
fwrite($this->_fp, $footer); fwrite($this->_fp, $zipData);
fseek($this->_fp, 0, SEEK_SET);
// return return strlen($zipData);
$len = ftell($this->_fp); }
fseek($this->_fp, 0, SEEK_SET);
return($len); // or own implementation
} else {
} // write central dir struct
$offset = ftell($this->_fp);
$dLength = 0;
foreach ($this->_centralDirStruct as $item) {
fwrite($this->_fp, $item);
$dLength += strlen($item);
}
// write footer
$footer = pack('VvvvvVVv',
0x06054b50,
0x0,
0x0,
count($this->_centralDirStruct),
count($this->_centralDirStruct),
$dLength,
$offset,
0x0);
fwrite($this->_fp, $footer);
// return
$len = ftell($this->_fp);
fseek($this->_fp, 0, SEEK_SET);
return $len;
}
}
} }