1665 Zeilen
48 KiB
PHP
1665 Zeilen
48 KiB
PHP
<?php
|
|
|
|
/**
|
|
* This Software is the property of Data Development and is protected
|
|
* by copyright law - it is NOT Freeware.
|
|
*
|
|
* Any unauthorized use of this software without a valid license
|
|
* is a violation of the license agreement and will be prosecuted by
|
|
* civil and criminal law.
|
|
*
|
|
* https://www.d3data.de
|
|
*
|
|
* @copyright (C) D3 Data Development (Inh. Thomas Dartsch)
|
|
* @author D3 Data Development - Daniel Seifert <support@shopmodule.com>
|
|
* @link http://www.oxidmodule.com
|
|
*/
|
|
|
|
namespace D3\ModCfg\Application\Model\Log;
|
|
|
|
use D3\ModCfg\Application\Model\d3bitmask;
|
|
use D3\ModCfg\Application\Model\d3database;
|
|
use D3\ModCfg\Application\Model\Configuration\d3_cfg_mod;
|
|
use D3\ModCfg\Application\Model\Parametercontainer\Registry as D3ModCfgRegistry;
|
|
use D3\ModCfg\Application\Model\Exception\d3ShopCompatibilityAdapterException;
|
|
use D3\ModCfg\Application\Model\Exception\d3_cfg_mod_exception;
|
|
use D3\ModCfg\Modules\Application\Controller\d3_oxshopcontrol_modcfg_extension;
|
|
use Doctrine\DBAL\Connection;
|
|
use Doctrine\DBAL\Driver\Exception as DBALDriverException;
|
|
use Doctrine\DBAL\Query\QueryBuilder;
|
|
use Exception;
|
|
use OxidEsales\Eshop\Application\Model\Shop;
|
|
use OxidEsales\Eshop\Core\ConfigFile;
|
|
use OxidEsales\Eshop\Core\Exception\StandardException;
|
|
use OxidEsales\Eshop\Core\Registry;
|
|
use OxidEsales\Eshop\Core\Request;
|
|
use OxidEsales\Eshop\Core\Model\BaseModel;
|
|
use OxidEsales\Eshop\Core\Email;
|
|
use OxidEsales\Eshop\Core\ShopControl;
|
|
use OxidEsales\Eshop\Core\Exception\DatabaseConnectionException;
|
|
use OxidEsales\Eshop\Core\Exception\DatabaseErrorException;
|
|
use Doctrine\DBAL\Exception as DBALException;
|
|
use OxidEsales\EshopCommunity\Internal\Container\ContainerFactory;
|
|
use OxidEsales\EshopCommunity\Internal\Framework\Database\ConnectionProviderInterface;
|
|
use OxidEsales\EshopCommunity\Internal\Framework\Database\QueryBuilderFactoryInterface;
|
|
use Psr\Container\ContainerExceptionInterface;
|
|
use Psr\Container\NotFoundExceptionInterface;
|
|
use Psr\Log\LoggerTrait;
|
|
|
|
class d3log extends BaseModel implements d3LogInterface
|
|
{
|
|
use LoggerTrait;
|
|
|
|
// single log levels
|
|
public const EMERGENCY = d3LogLevel::EMERGENCY; // Int 0, Bit 1
|
|
public const ALERT = d3LogLevel::ALERT; // Int 1, Bit 2
|
|
public const CRITICAL = d3LogLevel::CRITICAL; // Int 2, Bit 4
|
|
public const ERROR = d3LogLevel::ERROR; // Int 3 Bit 8
|
|
public const WARNING = d3LogLevel::WARNING; // Int 4 Bit 16
|
|
public const NOTICE = d3LogLevel::NOTICE; // Int 5 Bit 32
|
|
public const INFO = d3LogLevel::INFO; // Int 6 Bit 64
|
|
public const DEBUG = d3LogLevel::DEBUG; // Int 7 Bit 128
|
|
public const TEST = d3LogLevel::TEST; // Int 8 Bit 256
|
|
public const NONE = d3LogLevel::NONE; // Int 12 Bit 4096
|
|
|
|
// ranged log levels
|
|
public const ERROR_AND_ABOVE = d3LogLevel::ERROR_AND_ABOVE; // Bit 15;
|
|
public const WARNING_AND_ABOVE = d3LogLevel::WARNING_AND_ABOVE; // Bit 31;
|
|
public const NOTICE_AND_ABOVE = d3LogLevel::NOTICE_AND_ABOVE; // Bit 63;
|
|
public const INFO_AND_ABOVE = d3LogLevel::INFO_AND_ABOVE; // Bit 127;
|
|
public const ALL = d3LogLevel::ALL; // Bit 4095 // accept 3 additional levels
|
|
|
|
public $aLogTypes = [
|
|
'EMERGENCY' => d3LogLevel::EMERGENCY,
|
|
'ALERT' => d3LogLevel::ALERT,
|
|
'CRITICAL' => d3LogLevel::CRITICAL,
|
|
'ERROR' => d3LogLevel::ERROR,
|
|
'WARNING' => d3LogLevel::WARNING,
|
|
'NOTICE' => d3LogLevel::NOTICE,
|
|
'INFO' => d3LogLevel::INFO,
|
|
'DEBUG' => d3LogLevel::DEBUG,
|
|
'TEST' => d3LogLevel::TEST,
|
|
];
|
|
|
|
public $aLogGroups = [
|
|
'info' => [
|
|
'INFO' => true,
|
|
'NOTICE' => true,
|
|
'WARNING' => true,
|
|
'EMERGENCY' => true,
|
|
'ALERT' => true,
|
|
'CRITICAL' => true,
|
|
'ERROR' => true,
|
|
],
|
|
'notice' => [
|
|
'NOTICE' => true,
|
|
'WARNING' => true,
|
|
'EMERGENCY' => true,
|
|
'ALERT' => true,
|
|
'CRITICAL' => true,
|
|
'ERROR' => true,
|
|
],
|
|
'warning' => [
|
|
'WARNING' => true,
|
|
'EMERGENCY' => true,
|
|
'ALERT' => true,
|
|
'CRITICAL' => true,
|
|
'ERROR' => true,
|
|
],
|
|
'error' => [
|
|
'EMERGENCY' => true,
|
|
'ALERT' => true,
|
|
'CRITICAL' => true,
|
|
'ERROR' => true,
|
|
],
|
|
'none' => [
|
|
],
|
|
];
|
|
|
|
/**
|
|
* Object registry provides storage for shared objects
|
|
*
|
|
* @var array
|
|
*/
|
|
protected static $_aRegistry = [];
|
|
|
|
protected $_blStandAloneUse = false; // set this, if other libraries aren't available
|
|
protected $_sClassName = self::class;
|
|
|
|
protected $_sCoreTbl = 'd3log'; // bc
|
|
protected $_sCoreTable = 'd3log';
|
|
|
|
protected static $_sD3CoreTable = 'd3log';
|
|
|
|
public $_iLogType = d3LogLevel::EMERGENCY;
|
|
|
|
private string $_sLogSetId = 'd3modcfg_lib';
|
|
|
|
public $sModID;
|
|
|
|
public $sProfileID;
|
|
|
|
public $aD3TypeList = [];
|
|
|
|
public $aD3ModIdList = [];
|
|
|
|
public $aD3ClassList = [];
|
|
|
|
protected $_aSkipSaveFields = ['oxcounter', 'oxtimestamp'];
|
|
|
|
protected $_iInfoMailLogMessageLength = 40;
|
|
|
|
public $pwrsearchval;
|
|
|
|
/**
|
|
* Adds a new variable to the Registry.
|
|
*
|
|
* @param string $key Name of the variable
|
|
* @param mixed $value Value of the variable
|
|
*
|
|
* @return bool
|
|
*/
|
|
public static function set($key, $value)
|
|
{
|
|
self::$_aRegistry[$key] = $value;
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Tests if given $key exists in registry
|
|
*
|
|
* @param string $key
|
|
*
|
|
* @return bool
|
|
*/
|
|
public static function has($key)
|
|
{
|
|
return isset(self::$_aRegistry[$key]);
|
|
}
|
|
|
|
/**
|
|
* Returns the value of the specified $key in the Registry.
|
|
*
|
|
* @param string $sModId
|
|
* @param int|null $iLogType
|
|
*
|
|
* @return d3log|false
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
*/
|
|
public static function get(string $sModId, ?int $iLogType = null)
|
|
{
|
|
if (Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
startProfile(__METHOD__);
|
|
}
|
|
|
|
if (! self::isCallable()) {
|
|
return false;
|
|
}
|
|
|
|
if (self::has($sModId)) {
|
|
if (Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
stopProfile(__METHOD__);
|
|
}
|
|
|
|
return self::$_aRegistry[$sModId];
|
|
} else {
|
|
/** @var d3log $oLog */
|
|
$oLog =oxNew(d3log::class, $sModId);
|
|
|
|
if ($iLogType === false) {
|
|
$iLogType = $oLog->getLogType();
|
|
}
|
|
$oLog->setModId($sModId);
|
|
$oLog->setLogType($iLogType);
|
|
self::set($sModId, $oLog);
|
|
|
|
if (Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
stopProfile(__METHOD__);
|
|
}
|
|
|
|
return self::$_aRegistry[$sModId];
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Returns the whole Registry as an array.
|
|
*
|
|
* @return array Whole Registry
|
|
*/
|
|
public static function getAll()
|
|
{
|
|
return self::$_aRegistry;
|
|
}
|
|
|
|
/**
|
|
* Removes a variable from the Registry.
|
|
*
|
|
* @param string $key Name of the variable
|
|
*
|
|
* @return bool
|
|
*/
|
|
public static function remove($key)
|
|
{
|
|
if (self::has($key)) {
|
|
unset(self::$_aRegistry[$key]);
|
|
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Removes all variables from the Registry.
|
|
*
|
|
* @return void
|
|
*/
|
|
public static function removeAll()
|
|
{
|
|
self::$_aRegistry = [];
|
|
|
|
return;
|
|
}
|
|
|
|
/**
|
|
* constructor
|
|
*/
|
|
public function __construct()
|
|
{
|
|
if ((bool) Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
startProfile(__METHOD__);
|
|
}
|
|
parent::__construct();
|
|
|
|
$this->init($this->_sCoreTable);
|
|
if ((bool) Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
stopProfile(__METHOD__);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $sModId
|
|
*
|
|
* @return d3log
|
|
*/
|
|
public function setModId($sModId)
|
|
{
|
|
$this->sModID = $sModId;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function d3getModId()
|
|
{
|
|
return $this->sModID;
|
|
}
|
|
|
|
/**
|
|
* @param string $sProfileId
|
|
*
|
|
* @return d3log
|
|
*/
|
|
public function setProfileId($sProfileId)
|
|
{
|
|
$this->sProfileID = $sProfileId;
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
*/
|
|
public function d3getProfileId()
|
|
{
|
|
return $this->sProfileID;
|
|
}
|
|
|
|
/**
|
|
* getLogType(d3log::INFO)
|
|
* getLogType(d3log::INFO, d3log::ERROR);
|
|
*
|
|
* @param int $iLogType1
|
|
* @param int|null $iLogType2
|
|
* @param int|null $iLogType3
|
|
*
|
|
* @return d3log
|
|
*/
|
|
public function setLogType($iLogType1, $iLogType2 = null, $iLogType3 = null)
|
|
{
|
|
$aArgs = func_get_args();
|
|
$bitmask = oxNew(d3bitmask::class);
|
|
|
|
unset($iLogType1);
|
|
unset($iLogType2);
|
|
unset($iLogType3);
|
|
|
|
$aLog = [];
|
|
foreach ($aArgs as $iLogType) {
|
|
// espacially for combined logtypes
|
|
foreach ($this->aLogTypes as $iGenLogType) {
|
|
if ($bitmask->isBitSet($iLogType, $this->getLogBit($iGenLogType))) {
|
|
$aLog[$this->getErrorModeName($iGenLogType)] = 1;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (count($aLog)) {
|
|
$this->_iLogType = $this->getLogTypeByArray($aLog);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param int $range
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getLogTypeListByRange($range = d3LogLevel::ALL)
|
|
{
|
|
$bitmask = oxNew(d3bitmask::class);
|
|
|
|
$types = [];
|
|
foreach ($this->aLogTypes as $iGenLogType) {
|
|
if ($bitmask->isBitSet($range, $this->getLogBit($iGenLogType))) {
|
|
$types[] = $this->getErrorModeName($iGenLogType);
|
|
}
|
|
}
|
|
|
|
return $types;
|
|
}
|
|
|
|
/**
|
|
* @return int
|
|
*/
|
|
public function getLogType()
|
|
{
|
|
return $this->_iLogType;
|
|
}
|
|
|
|
/**
|
|
* @param int $iLogType
|
|
* @param string $sClass
|
|
* @param string $sFnc
|
|
* @param int $iLine
|
|
* @param string|null $sAction
|
|
* @param string|null $mText
|
|
* @param bool $blDie
|
|
*
|
|
* @return d3log
|
|
*/
|
|
public function log(
|
|
$iLogType = d3LogLevel::EMERGENCY,
|
|
$sClass = self::class,
|
|
$sFnc = __FUNCTION__,
|
|
$iLine = __LINE__,
|
|
$sAction = null,
|
|
$mText = null,
|
|
$blDie = false
|
|
) {
|
|
if ((bool) Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
startProfile(__METHOD__);
|
|
}
|
|
|
|
try {
|
|
$sSessID = Registry::getSession()->getId();
|
|
$this->sModID ? $sModID = $this->sModID : $sModID = 'empty';
|
|
$mText = is_string($mText) ? $mText : print_r($mText, true);
|
|
//$this->sModID definiert den Namen des Moduls, das geloggt werden soll -> tabellenfeld oxmodid
|
|
// Beide Objektwerte sollten immer nach der Objekterstellung nach 'oxNew' gesetzt werden
|
|
|
|
if ($this->getErrorMode($iLogType)) {
|
|
$this->setId();
|
|
$aContent = [
|
|
'oxshopid' => Registry::getConfig()->getShopId(),
|
|
'oxsessid' => $sSessID,
|
|
'oxlogtype' => strtolower($this->getErrorModeName($iLogType)),
|
|
'oxtime' => date('Y-m-d H:i:s'),
|
|
'oxmodid' => $sModID,
|
|
'oxprofileid' => $this->d3getProfileId() ?: 'none',
|
|
'oxclass' => $sClass,
|
|
'oxfnc' => $sFnc,
|
|
'oxline' => $iLine,
|
|
'oxaction' => $sAction,
|
|
'oxtext' => $mText,
|
|
];
|
|
|
|
$this->assign($aContent);
|
|
$this->insert();
|
|
$this->_handleMailMessage();
|
|
D3ModCfgRegistry::getInstance()->add($this);
|
|
}
|
|
} catch (DBALException|DatabaseConnectionException|DatabaseErrorException|d3ShopCompatibilityAdapterException|d3_cfg_mod_exception $e) {
|
|
Registry::getLogger()->error($e->getMessage(), [$e]);
|
|
}
|
|
|
|
try {
|
|
$this->_handleDie($mText, $blDie);
|
|
} catch (StandardException $e) {
|
|
Registry::getLogger()->error($e->getMessage(), [$e]);
|
|
}
|
|
|
|
if ((bool) Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
stopProfile(__METHOD__);
|
|
}
|
|
|
|
return $this;
|
|
}
|
|
|
|
/**
|
|
* @param string $sClass
|
|
* @param string $sFnc
|
|
* @param int $iLine
|
|
* @param null $sAction
|
|
* @param null $mText
|
|
* @param bool $blDie
|
|
* @return d3log
|
|
*/
|
|
public function emergency($sClass = self::class, $sFnc = __FUNCTION__, $iLine = __LINE__, $sAction = null, $mText = null, $blDie = false)
|
|
{
|
|
return $this->log(d3LogLevel::EMERGENCY, $sClass, $sFnc, $iLine, $sAction, $mText, $blDie);
|
|
}
|
|
|
|
/**
|
|
* @param string $sClass
|
|
* @param string $sFnc
|
|
* @param int $iLine
|
|
* @param null $sAction
|
|
* @param null $mText
|
|
* @param bool $blDie
|
|
* @return d3log
|
|
*/
|
|
public function alert($sClass = self::class, $sFnc = __FUNCTION__, $iLine = __LINE__, $sAction = null, $mText = null, $blDie = false)
|
|
{
|
|
return $this->log(d3LogLevel::ALERT, $sClass, $sFnc, $iLine, $sAction, $mText, $blDie);
|
|
}
|
|
|
|
/**
|
|
* @param string $sClass
|
|
* @param string $sFnc
|
|
* @param int $iLine
|
|
* @param null $sAction
|
|
* @param null $mText
|
|
* @param bool $blDie
|
|
* @return d3log
|
|
*/
|
|
public function critical($sClass = self::class, $sFnc = __FUNCTION__, $iLine = __LINE__, $sAction = null, $mText = null, $blDie = false)
|
|
{
|
|
return $this->log(d3LogLevel::CRITICAL, $sClass, $sFnc, $iLine, $sAction, $mText, $blDie);
|
|
}
|
|
|
|
/**
|
|
* @param string $sClass
|
|
* @param string $sFnc
|
|
* @param int $iLine
|
|
* @param null $sAction
|
|
* @param null $mText
|
|
* @param bool $blDie
|
|
* @return d3log
|
|
*/
|
|
public function error($sClass = self::class, $sFnc = __FUNCTION__, $iLine = __LINE__, $sAction = null, $mText = null, $blDie = false)
|
|
{
|
|
return $this->log(d3LogLevel::ERROR, $sClass, $sFnc, $iLine, $sAction, $mText, $blDie);
|
|
}
|
|
|
|
/**
|
|
* @param string $sClass
|
|
* @param string $sFnc
|
|
* @param int $iLine
|
|
* @param null $sAction
|
|
* @param null $mText
|
|
* @param bool $blDie
|
|
* @return d3log
|
|
*/
|
|
public function warning($sClass = self::class, $sFnc = __FUNCTION__, $iLine = __LINE__, $sAction = null, $mText = null, $blDie = false)
|
|
{
|
|
return $this->log(d3LogLevel::WARNING, $sClass, $sFnc, $iLine, $sAction, $mText, $blDie);
|
|
}
|
|
|
|
/**
|
|
* @param string $sClass
|
|
* @param string $sFnc
|
|
* @param int $iLine
|
|
* @param null $sAction
|
|
* @param null $mText
|
|
* @param bool $blDie
|
|
* @return d3log
|
|
*/
|
|
public function notice($sClass = self::class, $sFnc = __FUNCTION__, $iLine = __LINE__, $sAction = null, $mText = null, $blDie = false)
|
|
{
|
|
return $this->log(d3LogLevel::NOTICE, $sClass, $sFnc, $iLine, $sAction, $mText, $blDie);
|
|
}
|
|
|
|
/**
|
|
* @param string $sClass
|
|
* @param string $sFnc
|
|
* @param int $iLine
|
|
* @param null $sAction
|
|
* @param null $mText
|
|
* @param bool $blDie
|
|
*
|
|
* @return d3log
|
|
*/
|
|
public function info($sClass = self::class, $sFnc = __FUNCTION__, $iLine = __LINE__, $sAction = null, $mText = null, $blDie = false)
|
|
{
|
|
return $this->log(d3LogLevel::INFO, $sClass, $sFnc, $iLine, $sAction, $mText, $blDie);
|
|
}
|
|
|
|
/**
|
|
* @param string $sClass
|
|
* @param string $sFnc
|
|
* @param int $iLine
|
|
* @param null $sAction
|
|
* @param null $mText
|
|
* @param bool $blDie
|
|
* @return d3log
|
|
*/
|
|
public function debug($sClass = self::class, $sFnc = __FUNCTION__, $iLine = __LINE__, $sAction = null, $mText = null, $blDie = false)
|
|
{
|
|
return $this->log(d3LogLevel::DEBUG, $sClass, $sFnc, $iLine, $sAction, $mText, $blDie);
|
|
}
|
|
|
|
/**
|
|
* @param string $sClass
|
|
* @param string $sFnc
|
|
* @param int $iLine
|
|
* @param null $sAction
|
|
* @param null $mText
|
|
* @param bool $blDie
|
|
* @return d3log
|
|
*/
|
|
public function test($sClass = self::class, $sFnc = __FUNCTION__, $iLine = __LINE__, $sAction = null, $mText = null, $blDie = false)
|
|
{
|
|
return $this->log(d3LogLevel::TEST, $sClass, $sFnc, $iLine, $sAction, $mText, $blDie);
|
|
}
|
|
|
|
/**
|
|
* @param int $iLogType
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getLogBit($iLogType)
|
|
{
|
|
return oxNew(d3bitmask::class)->getIntByBitPosition($iLogType);
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getErrorModes()
|
|
{
|
|
// $iError = $this->getLogType();
|
|
|
|
$aLogTypeStatus = [];
|
|
foreach ($this->aLogTypes as $sLogType => $iLogType) {
|
|
$aLogTypeStatus[$sLogType] = $this->getErrorMode($iLogType);
|
|
}
|
|
|
|
return $aLogTypeStatus;
|
|
}
|
|
|
|
/**
|
|
* @param int $iErrorMode
|
|
*
|
|
* @return bool
|
|
*/
|
|
public function getErrorMode($iErrorMode)
|
|
{
|
|
if ((bool) Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
startProfile(__METHOD__);
|
|
}
|
|
|
|
$iError = $this->getLogType();
|
|
$iLogBit = $this->getLogBit($iErrorMode);
|
|
$blReturn = oxNew(d3bitmask::class)->isBitSet($iError, $iLogBit);
|
|
|
|
if ((bool) Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
stopProfile(__METHOD__);
|
|
}
|
|
|
|
return $blReturn;
|
|
}
|
|
|
|
/**
|
|
* @param $sStatus
|
|
* @param $oSet
|
|
* @return bool
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
*/
|
|
public function getLogStatus($sStatus, $oSet = false)
|
|
{
|
|
unset($oSet);
|
|
|
|
if (is_int($sStatus)) {
|
|
$flipped = array_flip($this->aLogTypes);
|
|
$sStatus = $flipped[$sStatus];
|
|
}
|
|
|
|
if ($this->getLogSet()->getValue('blLog_useExtendedLogging')) {
|
|
return $this->_getLogStatusExtended($sStatus);
|
|
} else {
|
|
if (strtoupper($sStatus) == 'DEBUG' ||
|
|
strtoupper($sStatus) == 'TEST'
|
|
) {
|
|
return $this->_getLogStatusExtended($sStatus);
|
|
}
|
|
|
|
$aLogLevelArray = $this->_convertLogLevelToModeArray($sStatus);
|
|
$aLogLevelKeys = array_keys($aLogLevelArray);
|
|
|
|
foreach ($this->getAllLogTypes() as $sErrorName => $iLogType) {
|
|
if (in_array($sErrorName, $aLogLevelKeys) && false == $this->getErrorMode($iLogType)) {
|
|
return false;
|
|
} elseif (false == in_array($sErrorName, $aLogLevelKeys) && $this->getErrorMode($iLogType)) {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $sStatus
|
|
*
|
|
* @return bool
|
|
*/
|
|
protected function _getLogStatusExtended($sStatus)
|
|
{
|
|
$iErrorMode = $this->getErrorModeId($sStatus);
|
|
|
|
return $this->getErrorMode($iErrorMode);
|
|
}
|
|
|
|
/**
|
|
* @param int $iErrorMode
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getErrorModeName($iErrorMode)
|
|
{
|
|
$aModTypeList = array_keys($this->aLogTypes);
|
|
|
|
return $aModTypeList[$iErrorMode];
|
|
}
|
|
|
|
/**
|
|
* @param string $sErrorName
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getErrorModeId($sErrorName)
|
|
{
|
|
$aModTypeList = array_keys($this->aLogTypes);
|
|
$iErrorMode = array_search(strtoupper($sErrorName), $aModTypeList);
|
|
|
|
return $iErrorMode;
|
|
}
|
|
|
|
/**
|
|
* @param array $aErrorModes
|
|
*
|
|
* @return int
|
|
*/
|
|
public function getLogTypeByArray($aErrorModes = [])
|
|
{
|
|
$aErrorModes = $this->_resolveArrayByLogTypes($aErrorModes);
|
|
|
|
return oxNew(d3bitmask::class)->getIntByBitMask($aErrorModes);
|
|
}
|
|
|
|
/**
|
|
* @param array $aErrorModes
|
|
*
|
|
* @return array
|
|
*/
|
|
protected function _resolveArrayByLogTypes($aErrorModes)
|
|
{
|
|
$aNewTypeArray = [];
|
|
$aErrorModes = array_change_key_case($aErrorModes, CASE_UPPER);
|
|
|
|
foreach (array_keys($this->aLogTypes) as $sTypeName) {
|
|
if (isset($aErrorModes[strtoupper($sTypeName)])) {
|
|
$aNewTypeArray[$sTypeName] = $aErrorModes[strtoupper($sTypeName)];
|
|
} else {
|
|
$aNewTypeArray[$sTypeName] = false;
|
|
}
|
|
}
|
|
|
|
return $aNewTypeArray;
|
|
}
|
|
|
|
/**
|
|
* @param int $iType
|
|
*
|
|
* @return int
|
|
*/
|
|
public function addLogType($iType)
|
|
{
|
|
$this->setLogType(oxNew(d3bitmask::class)->addBit($this->getLogType(), $this->getLogBit($iType)));
|
|
|
|
return $this->getLogType();
|
|
}
|
|
|
|
/**
|
|
* @param int $iType
|
|
*
|
|
* @return int
|
|
*/
|
|
public function removeLogType($iType)
|
|
{
|
|
$this->setLogType(oxNew(d3bitmask::class)->removeBit($this->getLogType(), $this->getLogBit($iType)));
|
|
|
|
return $this->getLogType();
|
|
}
|
|
|
|
/**
|
|
* @return int|false
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
*/
|
|
public function convertAdminLogSettings()
|
|
{
|
|
$aLog = [];
|
|
if ($this->getLogSet()->getValue('blLog_useExtendedLogging') &&
|
|
Registry::get(Request::class)->getRequestEscapedParameter('logtypes') &&
|
|
is_array(Registry::get(Request::class)->getRequestEscapedParameter('logtypes'))
|
|
) {
|
|
foreach (Registry::get(Request::class)->getRequestEscapedParameter('logtypes') as $iType => $blStatus) {
|
|
$aLog[$this->getErrorModeName($iType)] = (bool)$blStatus;
|
|
}
|
|
} elseif (Registry::get(Request::class)->getRequestEscapedParameter('loglevel') !== null) {
|
|
$aLog = $this->_convertLogLevelToModeArray(Registry::get(Request::class)->getRequestEscapedParameter('loglevel'));
|
|
|
|
$aLogTypes = Registry::get(Request::class)->getRequestEscapedParameter('logtypes');
|
|
|
|
/** set DEBUG mode */
|
|
if ($aLogTypes && is_array($aLogTypes) && isset($aLogTypes['7'])) {
|
|
$aLog['DEBUG'] = $aLogTypes['7'] ? true : false;
|
|
}
|
|
|
|
/** set TEST mode */
|
|
if ($aLogTypes && is_array($aLogTypes) && isset($aLogTypes['8'])) {
|
|
$aLog['TEST'] = $aLogTypes['8'] ? true : false;
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
|
|
if (count($aLog)) {
|
|
return $this->getLogTypeByArray($aLog);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
/**
|
|
* @param string $sLogLevel
|
|
*
|
|
* @return array
|
|
*/
|
|
protected function _convertLogLevelToModeArray($sLogLevel)
|
|
{
|
|
if (!$sLogLevel) {
|
|
return [];
|
|
}
|
|
|
|
$aLog = $this->aLogGroups[strtolower($sLogLevel)];
|
|
|
|
if (!is_array($aLog)) {
|
|
$aLog = [];
|
|
}
|
|
|
|
return $aLog;
|
|
}
|
|
|
|
/**
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
* @throws StandardException
|
|
* @throws d3ShopCompatibilityAdapterException
|
|
* @throws d3_cfg_mod_exception
|
|
*/
|
|
public function setBacktraceLog()
|
|
{
|
|
$this->Log();
|
|
debug_print_backtrace();
|
|
}
|
|
|
|
/**
|
|
* @param bool $forceCoreTable
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getSqlActiveSnippet($forceCoreTable = false)
|
|
{
|
|
unset($forceCoreTable);
|
|
return "1";
|
|
}
|
|
|
|
/**
|
|
* check, if mailsend has to be intitiated
|
|
* @return bool
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
*/
|
|
protected function _checkMailMessage()
|
|
{
|
|
if ($this->_checkMailMessageSlot(1) || $this->_checkMailMessageSlot(2)) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param $iSlot
|
|
* @return bool
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
*/
|
|
protected function _checkMailMessageSlot($iSlot)
|
|
{
|
|
if ((bool) Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
startProfile(__METHOD__);
|
|
}
|
|
|
|
$sAdrFieldName = 'sLog_messageadr'.$iSlot;
|
|
$sErrLevelFieldName = 'sLog_messageerrlevel'.$iSlot;
|
|
$sTimeStampFieldName = 'sLog_messagetimestamp'.$iSlot;
|
|
|
|
if ($this->getLogSet()->getValue($sAdrFieldName) &&
|
|
$this->getLogSet()->getValue($sErrLevelFieldName) &&
|
|
(
|
|
false == $this->getLogSet()->getValue($sTimeStampFieldName) ||
|
|
($this->getLogSet()->getValue($sTimeStampFieldName) < $this->_getLastReqMailTimeStamp($iSlot))
|
|
)
|
|
) {
|
|
if ((bool) Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
stopProfile(__METHOD__);
|
|
}
|
|
return true;
|
|
}
|
|
|
|
if ((bool) Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
stopProfile(__METHOD__);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
*/
|
|
public function getUsedMailMessageSlots()
|
|
{
|
|
$sAdrBaseFieldName = 'sLog_messageadr';
|
|
$aSlots = [];
|
|
|
|
for ($i = 1; $i < 100; $i++) {
|
|
$sAdrFieldName = $sAdrBaseFieldName.$i;
|
|
if (strlen($this->getLogSet()->getValue($sAdrFieldName))) {
|
|
$aSlots[] = $i;
|
|
} else {
|
|
break;
|
|
};
|
|
}
|
|
|
|
return $aSlots;
|
|
}
|
|
|
|
/**
|
|
* get timestamp of last required mailsend time
|
|
* @param $iSlot
|
|
* @return int
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
*/
|
|
protected function _getLastReqMailTimeStamp($iSlot)
|
|
{
|
|
$iDiff = match ($this->getLogSet()->getValue('sLog_messageintervaltype' . $iSlot)) {
|
|
'hour' => 60 * 60,
|
|
'day' => 60 * 60 * 24,
|
|
'minute' => 60,
|
|
default => 0,
|
|
};
|
|
|
|
$iDiff *= $this->getLogSet()->getValue('sLog_messageinterval' . $iSlot);
|
|
|
|
return time() - $iDiff;
|
|
}
|
|
|
|
/**
|
|
* send info mail to setted mail adresses
|
|
* @throws ContainerExceptionInterface
|
|
* @throws DBALDriverException
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
* @throws NotFoundExceptionInterface
|
|
* @throws StandardException
|
|
* @throws d3ShopCompatibilityAdapterException
|
|
* @throws d3_cfg_mod_exception
|
|
*/
|
|
protected function _sendMailMessage()
|
|
{
|
|
if ((bool) Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
startProfile(__METHOD__);
|
|
}
|
|
/** @var Connection $db */
|
|
$db = ContainerFactory::getInstance()->getContainer()->get(ConnectionProviderInterface::class)->get();
|
|
|
|
foreach ($this->getUsedMailMessageSlots() as $iSlotId) {
|
|
if ($this->_checkMailMessageSlot($iSlotId)) {
|
|
$aErrorStatus = $db->prepare($this->_getMailDataSelect($iSlotId))->executeQuery()->fetchAllAssociative();
|
|
|
|
if (count($aErrorStatus)) {
|
|
/** @var Email $oEMail */
|
|
$oEMail = oxNew(Email::class);
|
|
$this->_sendLogInfoMail(
|
|
$oEMail,
|
|
$this->getLogSet()->getValue('sLog_messageadr'.$iSlotId),
|
|
$this->_getMailSubject(),
|
|
$this->_getMailContent($aErrorStatus)
|
|
);
|
|
|
|
$this->getLogSet()->setValue('sLog_messagetimestamp'.$iSlotId, time());
|
|
$this->getLogSet()->save();
|
|
}
|
|
}
|
|
}
|
|
|
|
if ((bool) Registry::get(ConfigFile::class)->getVar('iDebug')) {
|
|
stopProfile(__METHOD__);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param Email $oEmail
|
|
* @param $sTo
|
|
* @param $sSubject
|
|
* @param $sBody
|
|
*/
|
|
protected function _sendLogInfoMail($oEmail, $sTo, $sSubject, $sBody)
|
|
{
|
|
/** @var Shop $oShop */
|
|
$oShop = Registry::getConfig()->getActiveShop();
|
|
|
|
if (! ($sFromAddress = Registry::getConfig()->getConfigParam('sLogInfoMailFromAddress'))) {
|
|
$sFromAddress = $oShop->getFieldData('oxorderemail');
|
|
}
|
|
|
|
$oEmail->setFrom($sFromAddress, $oShop->__get('oxshops__oxname')->getRawValue());
|
|
$oEmail->setSmtp($oShop);
|
|
|
|
if (is_array($sTo)) {
|
|
foreach ($sTo as $sAddress) {
|
|
$oEmail->setRecipient($sAddress, "");
|
|
$oEmail->setReplyTo($sAddress, "");
|
|
}
|
|
} else {
|
|
$oEmail->setRecipient($sTo, "");
|
|
$oEmail->setReplyTo($sTo, "");
|
|
}
|
|
|
|
//may be changed later
|
|
$oEmail->isHTML(true);
|
|
|
|
$oEmail->setSubject($sSubject);
|
|
$oEmail->setBody($sBody);
|
|
|
|
$oEmail->send();
|
|
}
|
|
|
|
/**
|
|
* create select to get status overview from database
|
|
*
|
|
* @param int $iSlot mail send configuration slot
|
|
*
|
|
* @return string
|
|
* @throws ContainerExceptionInterface
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
protected function _getMailDataSelect($iSlot)
|
|
{
|
|
/** @var Connection $db */
|
|
$db = ContainerFactory::getInstance()->getContainer()->get(ConnectionProviderInterface::class)->get();
|
|
|
|
$sWhere = $this->getLogSet()->getValue('sLog_messagetimestamp' . $iSlot) ? "oxtime > " . $db->quote(
|
|
date('Y-m-d H:i:s', $this->getLogSet()->getValue('sLog_messagetimestamp' . $iSlot))
|
|
) . " " : '1 ';
|
|
|
|
$aLevelFilter = [];
|
|
switch ($this->getLogSet()->getValue('sLog_messageerrlevel' . $iSlot)) {
|
|
case 'warning':
|
|
$aLevelFilter = ['emergency', 'alert', 'critical', 'error', 'warning'];
|
|
break;
|
|
case 'error':
|
|
$aLevelFilter = ['emergency', 'alert', 'critical', 'error'];
|
|
break;
|
|
case 'critical':
|
|
$aLevelFilter = ['emergency', 'alert', 'critical'];
|
|
break;
|
|
case 'alert':
|
|
$aLevelFilter = ['emergency', 'alert'];
|
|
break;
|
|
case 'emergency':
|
|
$aLevelFilter = ['emergency'];
|
|
break;
|
|
}
|
|
|
|
if (count($aLevelFilter)) {
|
|
$sWhere .= ' AND oxlogtype IN ("' . implode('","', $aLevelFilter) . '") ';
|
|
}
|
|
|
|
$sSelect = "SELECT count(oxlogtype) as counter, oxlogtype, oxmodid, CONCAT(substr(oxtext, 1, ".$this->_iInfoMailLogMessageLength."),'...') as text
|
|
FROM " . $this->getViewName() . "
|
|
WHERE " . $sWhere . " AND oxlogtype IS NOT NULL
|
|
GROUP BY oxmodid, oxlogtype, text
|
|
ORDER BY FIELD(oxlogtype,".$this->getLogTypePriorityList4Query()."), counter DESC";
|
|
|
|
return $sSelect;
|
|
}
|
|
|
|
/**
|
|
* generate subject for owner info mail
|
|
*
|
|
* @return string
|
|
*/
|
|
protected function _getMailSubject()
|
|
{
|
|
/** @var Shop $oShop */
|
|
$oShop = Registry::getConfig()->getActiveShop();
|
|
$iDefaultLang = Registry::getConfig()->getConfigParam('sDefaultLang');
|
|
$oLang = Registry::getLang();
|
|
|
|
$sText = sprintf(
|
|
$oLang->translateString('D3_LOGMAIL_SUBJECT', $iDefaultLang, true),
|
|
$oShop->getFieldData('oxname'),
|
|
$oShop->getFieldData('oxurl')
|
|
);
|
|
|
|
return $sText;
|
|
}
|
|
|
|
/**
|
|
* generate content by database data for owner info mail
|
|
*
|
|
* @param array $aStatus status data
|
|
*
|
|
* @return string
|
|
*/
|
|
protected function _getMailContent($aStatus)
|
|
{
|
|
$iDefaultLang = Registry::getConfig()->getConfigParam('sDefaultLang');
|
|
$oLang = Registry::getLang();
|
|
|
|
$sText = $oLang->translateString('D3_LOGMAIL_HEADLINE', $iDefaultLang, true);
|
|
$sText .= "<br><br>";
|
|
|
|
$sText .= "<table style='border: 1px solid silver;'>";
|
|
foreach ($aStatus as $aUniqueStatus) {
|
|
$aUniqueStatus = array_change_key_case($aUniqueStatus, CASE_UPPER);
|
|
$sText .= "<tr><td>".$aUniqueStatus['COUNTER']."x</td>";
|
|
$sText .= "<td>".$aUniqueStatus['OXLOGTYPE']."</td>";
|
|
$sText .= "<td>".sprintf(
|
|
$oLang->translateString('D3_LOGMAIL_INMODULE', $iDefaultLang, true),
|
|
$aUniqueStatus['OXMODID']
|
|
)."</td>";
|
|
$sText .= "<td>".str_replace([chr(10), chr(13)], '', $aUniqueStatus['TEXT'])."</td></tr>";
|
|
}
|
|
$sText .= "</table>";
|
|
|
|
$sText .= "<br>";
|
|
$sText .= $oLang->translateString('D3_LOGMAIL_DESC', $iDefaultLang, true)."<br><br>";
|
|
$sText .= $oLang->translateString('D3_LOGMAIL_LEGENDE', $iDefaultLang, true);
|
|
$sText .= $oLang->translateString('D3_LOGTYPE_DESC', $iDefaultLang, true);
|
|
|
|
return $sText;
|
|
}
|
|
|
|
/**
|
|
* @param bool $blGetDebug
|
|
* @param bool $blGetTestMode
|
|
*
|
|
* @return array
|
|
*/
|
|
public function getAllLogTypes($blGetDebug = false, $blGetTestMode = false)
|
|
{
|
|
$aTypes = $this->aLogTypes;
|
|
|
|
if (false == $blGetDebug) {
|
|
unset($aTypes['DEBUG']);
|
|
}
|
|
|
|
if (false == $blGetTestMode) {
|
|
unset($aTypes['TEST']);
|
|
}
|
|
|
|
return $aTypes;
|
|
}
|
|
|
|
/**
|
|
* @param string $sModId
|
|
* @return array
|
|
* @throws ContainerExceptionInterface
|
|
* @throws DBALDriverException
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
public function getLogTypeList($sModId = '')
|
|
{
|
|
if (false == $this->aD3TypeList || false == count($this->aD3TypeList)) {
|
|
/** @var QueryBuilder $qb */
|
|
$qb = ContainerFactory::getInstance()->getContainer()->get(QueryBuilderFactoryInterface::class)->create();
|
|
|
|
$qb->select('DISTINCT oxlogtype')
|
|
->from($this->getCoreTableName())
|
|
->orderBy('FIELD(oxlogtype,'.$this->getLogTypePriorityList4Query().')');
|
|
|
|
if ($sModId) {
|
|
$qb->where(
|
|
$qb->expr()->like('oxmodid', $qb->createNamedParameter('%'.$sModId.'%'))
|
|
);
|
|
}
|
|
$aRecords = $qb->execute()->fetchAllAssociative();
|
|
|
|
$this->aD3TypeList = [];
|
|
|
|
if (count($aRecords)) {
|
|
foreach ($aRecords as $aRecord) {
|
|
$aRecord = array_change_key_case($aRecord, CASE_UPPER);
|
|
$this->aD3TypeList[] = $aRecord['OXLOGTYPE'];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this->aD3TypeList;
|
|
}
|
|
|
|
public function getLogTypePriorityList()
|
|
{
|
|
return array_keys($this->aLogTypes);
|
|
}
|
|
|
|
/**
|
|
* @return string
|
|
* @throws ContainerExceptionInterface
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
public function getLogTypePriorityList4Query(): string
|
|
{
|
|
/** @var Connection $db */
|
|
$db = ContainerFactory::getInstance()->getContainer()->get(ConnectionProviderInterface::class)->get();
|
|
return implode(',', array_map([$db, 'quote'], $this->getLogTypePriorityList()));
|
|
}
|
|
|
|
/**
|
|
* @param string $sModId
|
|
* @return array
|
|
* @throws ContainerExceptionInterface
|
|
* @throws DBALDriverException
|
|
* @throws DBALException
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
public function getModIdList($sModId = '')
|
|
{
|
|
if (false == $this->aD3ModIdList || false == count($this->aD3ModIdList)) {
|
|
/** @var QueryBuilder $qb */
|
|
$qb = ContainerFactory::getInstance()->getContainer()->get(QueryBuilderFactoryInterface::class)->create();
|
|
$qb->select('DISTINCT oxmodid')
|
|
->from($this->getCoreTableName())
|
|
->orderBy('oxmodid');
|
|
|
|
if ($sModId) {
|
|
$qb->where($qb->expr()->like('oxmodid', $qb->createNamedParameter('%'.$sModId.'%')));
|
|
}
|
|
|
|
$aRecords = $qb->execute()->fetchAllAssociative();
|
|
|
|
$this->aD3ModIdList = [];
|
|
|
|
if (count($aRecords)) {
|
|
foreach ($aRecords as $aRecord) {
|
|
$aRecord = array_change_key_case($aRecord, CASE_UPPER);
|
|
$this->aD3ModIdList[] = $aRecord['OXMODID'];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this->aD3ModIdList;
|
|
}
|
|
|
|
/**
|
|
* @param string $sModId
|
|
* @return array
|
|
* @throws ContainerExceptionInterface
|
|
* @throws DBALDriverException
|
|
* @throws DBALException
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
public function getClassList($sModId = '')
|
|
{
|
|
if (false == $this->aD3ClassList || false == count($this->aD3ClassList)) {
|
|
/** @var QueryBuilder $qb */
|
|
$qb = ContainerFactory::getInstance()->getContainer()->get(QueryBuilderFactoryInterface::class)->create();
|
|
$qb->select('DISTINCT oxclass')
|
|
->from($this->getCoreTableName())
|
|
->orderBy('oxclass');
|
|
|
|
if ($sModId) {
|
|
$qb->where($qb->expr()->like('oxmodid', $qb->createNamedParameter('%'.$sModId.'%')));
|
|
}
|
|
|
|
$aRecords = $qb->execute()->fetchAllAssociative();
|
|
$this->aD3ClassList = [];
|
|
|
|
if (count($aRecords)) {
|
|
foreach ($aRecords as $aRecord) {
|
|
$aRecord = array_change_key_case($aRecord, CASE_UPPER);
|
|
$this->aD3ClassList[] = $aRecord['OXCLASS'];
|
|
}
|
|
}
|
|
}
|
|
|
|
return $this->aD3ClassList;
|
|
}
|
|
|
|
/**
|
|
* @param bool $sModId
|
|
* @param bool $sType
|
|
* @param bool $sFromTime
|
|
* @param bool $sToTime
|
|
* @return QueryBuilder
|
|
* @throws ContainerExceptionInterface
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
protected function _getDelSql($sModId = false, $sType = false, $sFromTime = false, $sToTime = false): QueryBuilder
|
|
{
|
|
/** @var QueryBuilder $qb */
|
|
$qb = ContainerFactory::getInstance()->getContainer()->get(QueryBuilderFactoryInterface::class)->create();
|
|
$qb->delete($this->getCoreTableName())
|
|
->where($qb->expr()->eq('oxshopid', $qb->createNamedParameter(Registry::getConfig()->getShopId())));
|
|
|
|
$sModId = $sModId ?: Registry::get(Request::class)->getRequestEscapedParameter('delete_oxmodid');
|
|
if ($sModId) {
|
|
$qb->andWhere($qb->expr()->eq('oxmodid', $qb->createNamedParameter($sModId)));
|
|
}
|
|
|
|
$sType = $sType ?: Registry::get(Request::class)->getRequestEscapedParameter('delete_oxtype');
|
|
if ($sType) {
|
|
$qb->andWhere($qb->expr()->eq('oxlogtype', $qb->createNamedParameter($sType)));
|
|
}
|
|
|
|
$sFromTime = $sFromTime ?: Registry::get(Request::class)->getRequestEscapedParameter('delete_oxfromtime');
|
|
if ($sFromTime) {
|
|
$qb->andWhere($qb->expr()->gt('oxtime', $qb->createNamedParameter($sFromTime)));
|
|
}
|
|
|
|
$sToTime = $sToTime ?: Registry::get(Request::class)->getRequestEscapedParameter('delete_oxtotime');
|
|
if ($sToTime) {
|
|
$qb->andWhere($qb->expr()->lt('oxtime', $qb->createNamedParameter($sToTime)));
|
|
}
|
|
|
|
return $qb;
|
|
}
|
|
|
|
/**
|
|
* @param bool $sModId
|
|
* @param bool $sType
|
|
* @param bool $sFromTime
|
|
* @param bool $sToTime
|
|
* @return int
|
|
* @throws ContainerExceptionInterface
|
|
* @throws DBALException
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
public function delLog($sModId = false, $sType = false, $sFromTime = false, $sToTime = false)
|
|
{
|
|
$sql = $this->_getDelSql($sModId, $sType, $sFromTime, $sToTime);
|
|
|
|
return $sql->execute();
|
|
}
|
|
|
|
/**
|
|
* @return array
|
|
*/
|
|
public function getSearchableFields()
|
|
{
|
|
$aSkipFields = ['oxid'];
|
|
$aFields = array_diff(array_keys($this->_aFieldNames), $aSkipFields);
|
|
|
|
return $aFields;
|
|
}
|
|
|
|
/**
|
|
* get logging modcfg object
|
|
*
|
|
* @return d3_cfg_mod
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
*/
|
|
public function getLogSet()
|
|
{
|
|
return d3_cfg_mod::get($this->_sLogSetId);
|
|
}
|
|
|
|
/**
|
|
* register an error handler
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
*/
|
|
public function registerErrorHandler()
|
|
{
|
|
if (class_exists(d3_cfg_mod::class) && d3_cfg_mod::isCallable()) {
|
|
try {
|
|
if ($this->getLogSet()->getId() && $this->getLogSet()->getValue('blLog_enableErrorReporting')) {
|
|
register_shutdown_function([$this, 'd3logShutDown']);
|
|
// E_USER_ERROR will catched twice, no additional handling needed
|
|
set_error_handler([$this, 'd3logError'], E_ALL ^ E_USER_ERROR);
|
|
}
|
|
} catch (Exception $e) {
|
|
unset($e);
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* log fatal error shutdowns
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
* @throws StandardException
|
|
* @throws d3ShopCompatibilityAdapterException
|
|
* @throws d3_cfg_mod_exception
|
|
*/
|
|
public function d3logShutDown()
|
|
{
|
|
$aError = error_get_last();
|
|
if (is_array($aError) && isset($aError['message'])) {
|
|
$this->d3logError($aError['type'], $aError['message'], $aError['file'], $aError['line']);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param $errno
|
|
* @param $errstr
|
|
* @param $errfile
|
|
* @param $errline
|
|
* @return bool
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
* @throws StandardException
|
|
* @throws d3ShopCompatibilityAdapterException
|
|
* @throws d3_cfg_mod_exception
|
|
*/
|
|
public function d3logError($errno, $errstr, $errfile, $errline)
|
|
{
|
|
$sClass = null;
|
|
$sFunction = null;
|
|
$sLine = null;
|
|
$sContent = null;
|
|
|
|
if (self::_d3extractClassName($errfile) == self::class) {
|
|
$aTrace = debug_backtrace();
|
|
$sClass = $aTrace[1]['class'] ?: self::_d3extractClassName($aTrace[1]['file']);
|
|
$sFunction = $aTrace[1]['function'];
|
|
$sLine = $aTrace[1]['line'];
|
|
|
|
foreach (array_keys($aTrace) as $key) {
|
|
if ($aTrace[$key]['object']) {
|
|
unset($aTrace[$key]['object']);
|
|
}
|
|
}
|
|
|
|
$sContent = trim(strip_tags($errstr)) . "\n\n";
|
|
$sContent .= print_r($aTrace, true);
|
|
} else {
|
|
$sClass = self::_d3extractClassName($errfile);
|
|
$sFunction = 'unknown';
|
|
$sLine = $errline;
|
|
$sContent = trim($errstr);
|
|
}
|
|
|
|
$this->Log(
|
|
self::_d3getErrorStatus($errno),
|
|
$sClass,
|
|
$sFunction,
|
|
$sLine,
|
|
'ErrorReporting',
|
|
$sContent . PHP_EOL . print_r($_REQUEST, true)
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param $errno
|
|
*
|
|
* @return int
|
|
*/
|
|
private function _d3getErrorStatus($errno)
|
|
{
|
|
$sErrState = null;
|
|
|
|
switch ((int)$errno) {
|
|
case E_NOTICE:
|
|
case E_USER_NOTICE:
|
|
$sErrState = d3LogLevel::NOTICE;
|
|
break;
|
|
case E_WARNING:
|
|
case E_USER_WARNING:
|
|
$sErrState = d3LogLevel::WARNING;
|
|
break;
|
|
case E_ERROR:
|
|
case E_RECOVERABLE_ERROR:
|
|
case E_USER_ERROR:
|
|
$sErrState = d3LogLevel::EMERGENCY;
|
|
break;
|
|
case E_STRICT:
|
|
$sErrState = d3LogLevel::WARNING;
|
|
break;
|
|
case null:
|
|
$sErrState = d3LogLevel::NONE;
|
|
break;
|
|
default:
|
|
$sErrState = d3LogLevel::ERROR;
|
|
}
|
|
|
|
if (version_compare(PHP_VERSION, '5.3', '>')) {
|
|
switch ((int)$errno) {
|
|
case E_DEPRECATED:
|
|
case E_USER_DEPRECATED:
|
|
$sErrState = d3LogLevel::WARNING;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $sErrState;
|
|
}
|
|
|
|
/**
|
|
* @param $sFile
|
|
*
|
|
* @return string
|
|
*/
|
|
private function _d3extractClassName($sFile)
|
|
{
|
|
$sFile = basename($sFile);
|
|
$iEnd = strrpos($sFile, '.');
|
|
|
|
return substr($sFile, 0, $iEnd);
|
|
}
|
|
|
|
/**
|
|
* show profiling
|
|
*/
|
|
public function d3GetProfiling()
|
|
{
|
|
$view = Registry::getConfig()->getActiveView();
|
|
/** @var d3_oxshopcontrol_modcfg_extension $oShopControl */
|
|
$oShopControl = oxNew(ShopControl::class);
|
|
$oShopControl->d3StopMonitoring($view);
|
|
}
|
|
|
|
/**
|
|
* check, if modcfg can get items
|
|
*
|
|
* @return bool
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
*/
|
|
public static function isCallable()
|
|
{
|
|
if (class_exists(d3database::class) &&
|
|
($oD3DataBase = d3database::getInstance()) &&
|
|
$oD3DataBase->checkTableExist(self::$_sD3CoreTable)
|
|
) {
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* @param $sLogType
|
|
*
|
|
* @return string
|
|
*/
|
|
public function getLogTypeTranslation($sLogType)
|
|
{
|
|
$sTranslationIdent = "D3_LOGTYPE_" . strtoupper($sLogType);
|
|
|
|
$sTranslation = Registry::getLang()->translateString($sTranslationIdent);
|
|
|
|
if ($sTranslation == $sTranslationIdent) {
|
|
return $sLogType;
|
|
} else {
|
|
return $sTranslation;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $sBaseModId
|
|
* @return string
|
|
* @throws DatabaseConnectionException
|
|
*/
|
|
public function d3BuildExportQuery($sBaseModId = '')
|
|
{
|
|
$aWhere = [];
|
|
|
|
$sModId = Registry::get(Request::class)->getRequestEscapedParameter('export_oxmodid');
|
|
if ($sModId) {
|
|
$aWhere['oxmodid'] = $sModId;
|
|
Registry::getConfig()->getActiveView()->addTplParam('oxmodid', $sModId);
|
|
}
|
|
|
|
$sTime = Registry::get(Request::class)->getRequestEscapedParameter('export_oxtime');
|
|
if ($sTime) {
|
|
$aWhere['oxtime'] = date('Y-m-d H:i:s', strtotime($sTime));
|
|
Registry::getConfig()->getActiveView()->addTplParam('oxtime', $sTime);
|
|
}
|
|
|
|
$sSessid = trim(Registry::get(Request::class)->getRequestEscapedParameter('export_oxsessid'));
|
|
if ($sSessid) {
|
|
$aWhere['oxsessid'] = $sSessid;
|
|
Registry::getConfig()->getActiveView()->addTplParam('oxsessid', $sSessid);
|
|
}
|
|
|
|
$sClass = trim(Registry::get(Request::class)->getRequestEscapedParameter('export_oxclass'));
|
|
if ($sClass) {
|
|
$aWhere['oxclass'] = $sClass;
|
|
Registry::getConfig()->getActiveView()->addTplParam('oxclass', $sClass);
|
|
}
|
|
|
|
$sSelect = $this->buildSelectString($aWhere);
|
|
|
|
/** @var Connection $db */
|
|
$db = ContainerFactory::getInstance()->getContainer()->get(ConnectionProviderInterface::class)->get();
|
|
|
|
$aSearch = ['oxtime ='];
|
|
$aReplace = ['oxtime >'];
|
|
if ($sBaseModId) {
|
|
$aSearch[] = ' where 1 ';
|
|
$aReplace[] = ' where 1 AND oxmodid LIKE '.$db->quote('%'.$sBaseModId.'%');
|
|
}
|
|
|
|
$sSelect = str_replace($aSearch, $aReplace, $sSelect);
|
|
|
|
return $sSelect;
|
|
}
|
|
|
|
/**
|
|
* @throws DBALException
|
|
* @throws DatabaseConnectionException
|
|
* @throws DatabaseErrorException
|
|
* @throws StandardException
|
|
* @throws d3ShopCompatibilityAdapterException
|
|
* @throws d3_cfg_mod_exception
|
|
*/
|
|
protected function _handleMailMessage()
|
|
{
|
|
if (false == $this->_blStandAloneUse) {
|
|
if ($this->_checkMailMessage()) {
|
|
$this->_sendMailMessage();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param $mText
|
|
* @param $blDie
|
|
*/
|
|
protected function _handleDie($mText, $blDie)
|
|
{
|
|
if ($blDie) {
|
|
die($mText);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* @param string $sModId
|
|
*
|
|
* @return string
|
|
* @throws DatabaseConnectionException
|
|
* @throws ContainerExceptionInterface
|
|
* @throws NotFoundExceptionInterface
|
|
*/
|
|
public function getItemCount($sModId = '')
|
|
{
|
|
$oQB = ContainerFactory::getInstance()->getContainer()->get(QueryBuilderFactoryInterface::class)->create();
|
|
$oQB->select('count(*)')
|
|
->from($this->getCoreTableName())
|
|
->setMaxResults(1)
|
|
;
|
|
|
|
if ($sModId) {
|
|
$oQB->where('oxmodid LIKE '.$oQB->createNamedParameter('%' . $sModId . '%'));
|
|
}
|
|
|
|
return $oQB->execute()->fetchOne();
|
|
}
|
|
}
|