![]() Server : Apache System : Linux server2.corals.io 4.18.0-348.2.1.el8_5.x86_64 #1 SMP Mon Nov 15 09:17:08 EST 2021 x86_64 User : corals ( 1002) PHP Version : 7.4.33 Disable Function : exec,passthru,shell_exec,system Directory : /home/corals/old/vendor/magento/module-reports/Model/ResourceModel/Report/ |
<?php /** * Copyright © Magento, Inc. All rights reserved. * See COPYING.txt for license details. */ namespace Magento\Reports\Model\ResourceModel\Report; /** * Abstract report aggregate resource model * @SuppressWarnings(PHPMD.CouplingBetweenObjects) * phpcs:disable Magento2.Classes.AbstractApi * @api * @since 100.0.2 */ abstract class AbstractReport extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { /** * Flag object * * @var \Magento\Reports\Model\Flag */ protected $_flag = null; /** * Logger instance * * @var \Psr\Log\LoggerInterface */ protected $_logger; /** * Locale date instance * * @var \Magento\Framework\Stdlib\DateTime\TimezoneInterface */ protected $_localeDate; /** * @var \Magento\Reports\Model\FlagFactory */ protected $_reportsFlagFactory; /** * @var \Magento\Framework\Stdlib\DateTime\DateTime */ protected $dateTime; /** * @var \Magento\Framework\Stdlib\DateTime\Timezone\Validator */ private $timezoneValidator; /** * Constructor * * @param \Magento\Framework\Model\ResourceModel\Db\Context $context * @param \Psr\Log\LoggerInterface $logger * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate * @param \Magento\Reports\Model\FlagFactory $reportsFlagFactory * @param \Magento\Framework\Stdlib\DateTime\Timezone\Validator $timezoneValidator * @param \Magento\Framework\Stdlib\DateTime\DateTime $dateTime * @param string|null $connectionName */ public function __construct( \Magento\Framework\Model\ResourceModel\Db\Context $context, \Psr\Log\LoggerInterface $logger, \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate, \Magento\Reports\Model\FlagFactory $reportsFlagFactory, \Magento\Framework\Stdlib\DateTime\Timezone\Validator $timezoneValidator, \Magento\Framework\Stdlib\DateTime\DateTime $dateTime, $connectionName = null ) { parent::__construct($context, $connectionName); $this->_logger = $logger; $this->_localeDate = $localeDate; $this->_reportsFlagFactory = $reportsFlagFactory; $this->timezoneValidator = $timezoneValidator; $this->dateTime = $dateTime; } /** * Retrieve flag object * * @return \Magento\Reports\Model\Flag */ protected function _getFlag() { if ($this->_flag === null) { $this->_flag = $this->_reportsFlagFactory->create(); } return $this->_flag; } /** * Saves flag * * @param string $code * @param mixed $value * @return $this */ protected function _setFlagData($code, $value = null) { $this->_getFlag()->setReportFlagCode($code)->unsetData()->loadSelf(); if ($value !== null) { $this->_getFlag()->setFlagData($value); } // touch last_update $this->_getFlag()->setLastUpdate($this->dateTime->gmtDate()); $this->_getFlag()->save(); return $this; } /** * Retrieve flag data * * @param string $code * @return mixed */ protected function _getFlagData($code) { $this->_getFlag()->setReportFlagCode($code)->unsetData()->loadSelf(); return $this->_getFlag()->getFlagData(); } /** * Truncate table * * @param string $table * @return $this */ protected function _truncateTable($table) { if ($this->getConnection()->getTransactionLevel() > 0) { $this->getConnection()->delete($table); } else { $this->getConnection()->truncateTable($table); } return $this; } /** * Clear report table by specified date range. * If specified source table parameters, * condition will be generated by source table sub-select. * * @param string $table * @param null|string $from * @param null|string $to * @param null|\Magento\Framework\DB\Select|string $subSelect * @param bool $doNotUseTruncate * @param \Magento\Framework\DB\Adapter\AdapterInterface $connection * @return $this */ protected function _clearTableByDateRange( $table, $from = null, $to = null, $subSelect = null, $doNotUseTruncate = false, $connection = null ) { if ($from === null && $to === null && !$doNotUseTruncate) { $this->_truncateTable($table); return $this; } if ($subSelect !== null) { $deleteCondition = $this->_makeConditionFromDateRangeSelect($subSelect, 'period', $connection); } else { $condition = []; if ($from !== null) { $condition[] = $this->getConnection()->quoteInto('period >= ?', $from); } if ($to !== null) { $condition[] = $this->getConnection()->quoteInto('period <= ?', $to); } $deleteCondition = implode(' AND ', $condition); } $this->getConnection()->delete($table, $deleteCondition); return $this; } /** * Generate table date range select * * @param string $table * @param string $column * @param string $whereColumn * @param null|string|\DateTimeInterface $from * @param null|string|\DateTimeInterface $to * @param [][] $additionalWhere * @param string $alias * @return \Magento\Framework\DB\Select */ protected function _getTableDateRangeSelect( $table, $column, $whereColumn, $from = null, $to = null, $additionalWhere = [], $alias = 'date_range_table' ) { $connection = $this->getConnection(); $select = $connection->select()->from( [$alias => $table], $connection->getDatePartSql( $this->getStoreTZOffsetQuery([$alias => $table], $alias . '.' . $column, $from, $to) ) )->distinct( true ); if ($from !== null) { $select->where($alias . '.' . $whereColumn . ' >= ?', $from); } if ($to !== null) { $select->where($alias . '.' . $whereColumn . ' <= ?', $to); } if (!empty($additionalWhere)) { foreach ($additionalWhere as $condition) { if (is_array($condition) && count($condition) == 2) { $condition = $connection->quoteInto($condition[0], $condition[1]); } elseif (is_array($condition)) { // Invalid condition continue; } $condition = str_replace('{{table}}', $connection->quoteIdentifier($alias), $condition); $select->where($condition); } } return $select; } /** * Make condition for using in where section from select statement with single date column * * @param \Magento\Framework\DB\Select $select * @param string $periodColumn * @param \Magento\Framework\DB\Adapter\AdapterInterface $connection * @return array|bool|string */ protected function _makeConditionFromDateRangeSelect($select, $periodColumn, $connection = null) { if (!$connection) { $connection = $this->getConnection(); } static $selectResultCache = []; $cacheKey = (string)$select; if (!array_key_exists($cacheKey, $selectResultCache)) { try { $selectResult = []; $query = $connection->query($select); while (true == ($date = $query->fetchColumn())) { $selectResult[] = $date; } } catch (\Exception $e) { $selectResult = false; } $selectResultCache[$cacheKey] = $selectResult; } else { $selectResult = $selectResultCache[$cacheKey]; } if ($selectResult === false) { return false; } $whereCondition = []; foreach ($selectResult as $date) { $whereCondition[] = $connection->prepareSqlCondition($periodColumn, ['like' => $date]); } $whereCondition = implode(' OR ', $whereCondition); if ($whereCondition == '') { $whereCondition = '1=0'; // FALSE condition! } return $whereCondition; } /** * Generate table date range select * * @param string $table * @param string $relatedTable * @param [] $joinCondition * @param string $column * @param string $whereColumn * @param string|null $from * @param string|null $to * @param [][] $additionalWhere * @param string $alias * @param string $relatedAlias * @return \Magento\Framework\DB\Select * @SuppressWarnings(PHPMD.ExcessiveParameterList) */ protected function _getTableDateRangeRelatedSelect( $table, $relatedTable, $joinCondition, $column, $whereColumn, $from = null, $to = null, $additionalWhere = [], $alias = 'date_range_table', $relatedAlias = 'related_date_range_table' ) { $connection = $this->getConnection(); $joinConditionSql = []; foreach ($joinCondition as $fkField => $pkField) { $joinConditionSql[] = sprintf('%s.%s = %s.%s', $alias, $fkField, $relatedAlias, $pkField); } $select = $connection->select()->from( [$alias => $table], $connection->getDatePartSql($connection->quoteIdentifier($alias . '.' . $column)) )->joinInner( [$relatedAlias => $relatedTable], implode(' AND ', $joinConditionSql), [] )->distinct( true ); if ($from !== null) { $select->where($relatedAlias . '.' . $whereColumn . ' >= ?', $from); } if ($to !== null) { $select->where($relatedAlias . '.' . $whereColumn . ' <= ?', $to); } if (!empty($additionalWhere)) { foreach ($additionalWhere as $condition) { if (is_array($condition) && count($condition) == 2) { $condition = $connection->quoteInto($condition[0], $condition[1]); } elseif (is_array($condition)) { // Invalid condition continue; } $condition = str_replace( ['{{table}}', '{{related_table}}'], [$connection->quoteIdentifier($alias), $connection->quoteIdentifier($relatedAlias)], $condition ); $select->where($condition); } } return $select; } /** * Retrieve query for attribute with timezone conversion * * @param string|[] $table * @param string $column * @param null|mixed $from * @param null|mixed $to * @param null|int|string|\Magento\Store\Model\Store $store * @param \Magento\Framework\DB\Adapter\AdapterInterface $connection * @return string */ public function getStoreTZOffsetQuery( $table, $column, $from = null, $to = null, $store = null, $connection = null ) { if (!$connection) { $connection = $this->getConnection(); } $column = $connection->quoteIdentifier($column); if (null === $from) { $selectOldest = $connection->select()->from($table, ["MIN({$column})"]); $from = $connection->fetchOne($selectOldest); if (null === $from) { $date = new \DateTime(); $from = $date->format('Y-m-d H:i:s'); } } $periods = $this->_getTZOffsetTransitions( $this->_localeDate->scopeDate($store)->format('e'), $from, $to ); if (empty($periods)) { return $column; } $query = ""; $periodsCount = count($periods); $i = 0; foreach ($periods as $offset => $timestamps) { $subParts = []; foreach ($timestamps as $ts) { $subParts[] = "({$column} between {$ts['from']} and {$ts['to']})"; } $then = $connection->getDateAddSql( $column, $offset, \Magento\Framework\DB\Adapter\AdapterInterface::INTERVAL_SECOND ); $query .= ++$i == $periodsCount ? $then : "CASE WHEN " . join(" OR ", $subParts) . " THEN {$then} ELSE "; } return $query . str_repeat('END ', count($periods) - 1); } /** * Retrieve transitions for offsets of given timezone * * @param string $timezone * @param mixed $from * @param mixed $to * @return array * @SuppressWarnings(PHPMD.NPathComplexity) */ protected function _getTZOffsetTransitions($timezone, $from = null, $to = null) { $tzTransitions = []; try { if (!empty($from)) { $from = $from instanceof \DateTimeInterface ? $from->getTimestamp() : (new \DateTime($from))->getTimestamp(); } $to = $to instanceof \DateTimeInterface ? $to : new \DateTime($to ?? 'now'); $nextPeriod = $this->getConnection()->formatDate( $to->format('Y-m-d H:i:s') ); $to = $to->getTimestamp(); $dtz = new \DateTimeZone($timezone); $transitions = $dtz->getTransitions(); for ($i = count($transitions) - 1; $i >= 0; $i--) { $tr = $transitions[$i]; try { $this->timezoneValidator->validate($tr['ts'], $to); } catch (\Magento\Framework\Exception\ValidatorException $e) { continue; } $tr['time'] = $this->getConnection()->formatDate( (new \DateTime($tr['time']))->format('Y-m-d H:i:s') ); $tzTransitions[$tr['offset']][] = ['from' => $tr['time'], 'to' => $nextPeriod]; if (!empty($from) && $tr['ts'] < $from) { break; } $nextPeriod = $tr['time']; } } catch (\Exception $e) { $this->_logger->critical($e); } return $tzTransitions; } }