diff --git a/application/Espo/Classes/Cleanup/Audit.php b/application/Espo/Classes/Cleanup/Audit.php new file mode 100644 index 0000000000..8b6161d839 --- /dev/null +++ b/application/Espo/Classes/Cleanup/Audit.php @@ -0,0 +1,104 @@ +. + * + * The interactive user interfaces in modified source and object code versions + * of this program must display Appropriate Legal Notices, as required under + * Section 5 of the GNU Affero General Public License version 3. + * + * In accordance with Section 7(b) of the GNU Affero General Public License version 3, + * these Appropriate Legal Notices must retain the display of the "EspoCRM" word. + ************************************************************************/ + +namespace Espo\Classes\Cleanup; + +use Espo\Core\Cleanup\Cleanup; +use Espo\Core\Field\DateTime; +use Espo\Core\Utils\Config; +use Espo\Core\Utils\Metadata; +use Espo\Entities\Note; +use Espo\ORM\EntityManager; + +/** + * @noinspection PhpUnused + */ +class Audit implements Cleanup +{ + private const PERIOD = '3 months'; + + public function __construct( + private Metadata $metadata, + private EntityManager $entityManager, + private Config $config + ) {} + + public function process(): void + { + if (!$this->config->get('cleanupAudit')) { + return; + } + + $entityTypeList = $this->getEntityTypeList(); + + foreach ($entityTypeList as $scope) { + $this->processEntityType($scope); + } + } + + private function processEntityType(string $entityType): void + { + $query = $this->entityManager + ->getQueryBuilder() + ->delete() + ->from(Note::ENTITY_TYPE) + ->where([ + 'parentType' => $entityType, + 'createdAt<' => $this->getBefore()->toString(), + 'type' => [Note::TYPE_UPDATE, Note::TYPE_STATUS], + ]) + ->build(); + + $this->entityManager->getQueryExecutor()->execute($query); + } + + /** + * @return string[] + */ + private function getEntityTypeList(): array + { + /** @var string[] $scopeList */ + $scopeList = array_keys($this->metadata->get(['scopes']) ?? []); + + $scopeList = array_filter($scopeList, function ($item) { + return $this->metadata->get(['scopes', $item, 'entity']) && + !$this->metadata->get(['scopes', $item, 'stream']); + }); + + return array_values($scopeList); + } + + private function getBefore(): DateTime + { + /** @var string $period */ + $period = $this->config->get('cleanupAuditPeriod') ?? self::PERIOD; + + return DateTime::createNow()->modify('-' . $period); + } +} diff --git a/application/Espo/Resources/defaults/config.php b/application/Espo/Resources/defaults/config.php index b09cba00a2..673953a3c3 100644 --- a/application/Espo/Resources/defaults/config.php +++ b/application/Espo/Resources/defaults/config.php @@ -234,6 +234,8 @@ return [ 'cleanupActionHistoryPeriod' => '15 days', 'cleanupAuthTokenPeriod' => '1 month', 'cleanupSubscribers' => true, + 'cleanupAudit' => true, + 'cleanupAuditPeriod' => '3 months', 'currencyFormat' => 2, 'currencyDecimalPlaces' => 2, 'aclAllowDeleteCreated' => false, diff --git a/application/Espo/Resources/defaults/systemConfig.php b/application/Espo/Resources/defaults/systemConfig.php index 54deb69e67..2821725531 100644 --- a/application/Espo/Resources/defaults/systemConfig.php +++ b/application/Espo/Resources/defaults/systemConfig.php @@ -191,6 +191,8 @@ return [ 'cleanupDeletedRecords', 'cleanupSubscribers', 'cleanupSubscribersPeriod', + 'cleanupAudit', + 'cleanupAuditPeriod', 'authTokenPreventConcurrent', 'emailParser', 'passwordRecoveryDisabled', diff --git a/application/Espo/Resources/metadata/app/cleanup.json b/application/Espo/Resources/metadata/app/cleanup.json index c671f83332..4508497fc6 100644 --- a/application/Espo/Resources/metadata/app/cleanup.json +++ b/application/Espo/Resources/metadata/app/cleanup.json @@ -21,5 +21,8 @@ }, "subscribers": { "className": "Espo\\Classes\\Cleanup\\Subscribers" + }, + "audit": { + "className": "Espo\\Classes\\Cleanup\\Audit" } }