Skip to content

Commit

Permalink
Clean up page_hits table where date_hit field is lower than --day…
Browse files Browse the repository at this point in the history
…s-old.
  • Loading branch information
biozshock committed Jan 27, 2024
1 parent 9f31c91 commit bf6947d
Show file tree
Hide file tree
Showing 8 changed files with 154 additions and 53 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,19 @@ on:
push:
branches:
- master
- '[0-9]+\-[0-9]+\-x'
- 'MTC\-[0-9]+'
pull_request:

jobs:
integration:
name: Integration tests
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
strategy:
matrix:
php-version: [ 7.4, 8.0 ]
php-version: [ 7.4, 8.0, 8.1 ]
steps:
- name: Checkout
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Setup PHP Environment
uses: shivammathur/setup-php@v2
with:
Expand Down
7 changes: 6 additions & 1 deletion Command/EventLogCleanupCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -42,14 +42,15 @@ protected function configure(): void
new InputOption('dry-run', 'r', InputOption::VALUE_NONE, 'Do a dry run without actually deleting anything.'),
new InputOption('campaign-lead', 'c', InputOption::VALUE_NONE, 'Purge only Campaign Lead Event Log Records'),
new InputOption('lead', 'l', InputOption::VALUE_NONE, 'Purge only Lead Event Log Records'),
new InputOption('page-hits', 'p', InputOption::VALUE_NONE, 'Purge only Hit (page_hit) Records'),
new InputOption('email-stats', 'm', InputOption::VALUE_NONE, 'Purge only Email Stats Records where the referenced email entry is currently not published and purge Email Stats Devices. Important: If referenced email is ever switched back to published, the contacts will get the email again.'),
new InputOption('email-stats-tokens', 't', InputOption::VALUE_NONE, 'Set only tokens fields in Email Stats Records to NULL. Important: This option can not be combined with any "-c", "-l" or "-m" flag in one command. And: If the option flag "-t" is not set, the NULL setting of tokens will not be done with the basis command, so if you just run mautic:leuchtfeuer:housekeeping without a flag)'),
new InputOption('cmp-id', 'i', InputOption::VALUE_OPTIONAL, 'Delete only campaign_lead_eventLog for a specific CampaignID', 'none'),
]
)
->setHelp(
<<<'EOT'
The <info>%command.name%</info> command is used to clean up the campaign_lead_event_log table, the lead_event_log table, the email_stats table (but only email_stats entries where the referenced email entry is currently not published) and the email_stats_devices table or just clean up the field tokens in email_stats if the option flag "-t" is set.
The <info>%command.name%</info> command is used to clean up the campaign_lead_event_log table, the lead_event_log table, the page_hits table, the email_stats table (but only email_stats entries where the referenced email entry is currently not published) and the email_stats_devices table or just clean up the field tokens in email_stats if the option flag "-t" is set.
<info>php %command.full_name%</info>
Expand All @@ -73,6 +74,9 @@ protected function configure(): void
Set tokens field in email_stats to NULL:
<info>php %command.full_name% --email-stats-tokens</info>
Purge only page_hits records
<info>php %command.full_name% --page-hits</info>
EOT
);
}
Expand All @@ -87,6 +91,7 @@ protected function execute(InputInterface $input, OutputInterface $output): int
EventLogCleanup::LEAD_EVENTS => $input->getOption('lead'),
EventLogCleanup::EMAIL_STATS => $input->getOption('email-stats'),
EventLogCleanup::EMAIL_STATS_TOKENS => $input->getOption('email-stats-tokens'),
EventLogCleanup::PAGE_HITS => $input->getOption('page-hits'),
];

if (0 === array_sum($operations)) {
Expand Down
85 changes: 46 additions & 39 deletions Config/config.php
Original file line number Diff line number Diff line change
@@ -1,54 +1,61 @@
<?php

return [
$configValue = [
'name' => 'Housekeeping by Leuchtfeuer',
'description' => 'Database Cleanup Command to delete lead_event_log table entries, campaign_lead_event_log table entries, email_stats table entries where the referenced email entry is currently not published and email_stats_devices table entries.',
'version' => '3.1.0',
'version' => '4.0.0',
'author' => 'Leuchtfeuer Digital Marketing GmbH',
'services' => [
'integrations' => [
'mautic.integration.housekeepingleuchtfeuer' => [
'class' => \MauticPlugin\LeuchtfeuerHousekeepingBundle\Integration\HousekeepingLeuchtfeuerIntegration::class,
'tags' => [
'mautic.integration',
'mautic.basic_integration',
],
];

if (version_compare(MAUTIC_VERSION, '5', '>=')) {
return $configValue;
}

$configValue['services'] = [
'integrations' => [
'mautic.integration.housekeepingleuchtfeuer' => [
'class' => \MauticPlugin\LeuchtfeuerHousekeepingBundle\Integration\HousekeepingLeuchtfeuerIntegration::class,
'tags' => [
'mautic.integration',
'mautic.basic_integration',
],
'housekeepingleuchtfeuer.integration.configuration' => [
'class' => \MauticPlugin\LeuchtfeuerHousekeepingBundle\Integration\Support\ConfigSupport::class,
'tags' => [
'mautic.config_integration',
],
],
'housekeepingleuchtfeuer.integration.configuration' => [
'class' => \MauticPlugin\LeuchtfeuerHousekeepingBundle\Integration\Support\ConfigSupport::class,
'tags' => [
'mautic.config_integration',
],
],
'command' => [
'mautic.leuchtfeuer.command.housekeeping' => [
'class' => \MauticPlugin\LeuchtfeuerHousekeepingBundle\Command\EventLogCleanupCommand::class,
'tag' => 'console.command',
'arguments' => [
'mautic.leuchtfeuer.service.event_log_cleanup',
],
],
'command' => [
'mautic.leuchtfeuer.command.housekeeping' => [
'class' => \MauticPlugin\LeuchtfeuerHousekeepingBundle\Command\EventLogCleanupCommand::class,
'tag' => 'console.command',
'arguments' => [
'mautic.leuchtfeuer.service.event_log_cleanup',
],
],
'models' => [],
'forms' => [],
'helpers' => [],
'other' => [
'mautic.leuchtfeuer.service.event_log_cleanup' => [
'class' => \MauticPlugin\LeuchtfeuerHousekeepingBundle\Service\EventLogCleanup::class,
'arguments' => [
'database_connection',
'%mautic.db_table_prefix%',
'mautic.housekeepingleuchtfeuer.config',
],
],
'models' => [],
'forms' => [],
'helpers' => [],
'other' => [
'mautic.leuchtfeuer.service.event_log_cleanup' => [
'class' => \MauticPlugin\LeuchtfeuerHousekeepingBundle\Service\EventLogCleanup::class,
'arguments' => [
'database_connection',
'%mautic.db_table_prefix%',
'mautic.housekeepingleuchtfeuer.config',
],
'mautic.housekeepingleuchtfeuer.config' => [
'class' => \MauticPlugin\LeuchtfeuerHousekeepingBundle\Integration\Config::class,
'arguments' => [
'mautic.integrations.helper',
],
],
'mautic.housekeepingleuchtfeuer.config' => [
'class' => \MauticPlugin\LeuchtfeuerHousekeepingBundle\Integration\Config::class,
'arguments' => [
'mautic.integrations.helper',
],
],
'parameters' => [],
],
'parameters' => [],
];

return $configValue;
32 changes: 32 additions & 0 deletions Config/services.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

use Mautic\CoreBundle\DependencyInjection\MauticCoreExtension;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

if (version_compare(MAUTIC_VERSION, '5', '<')) {
return;
}

return static function (ContainerConfigurator $configurator): void {
$services = $configurator->services()
->defaults()
->autowire()
->autoconfigure()
->public();

$services->load('MauticPlugin\\LeuchtfeuerHousekeepingBundle\\', '../')
->exclude('../{'.implode(',', MauticCoreExtension::DEFAULT_EXCLUDES).'}');

$services->get(\MauticPlugin\LeuchtfeuerHousekeepingBundle\Integration\HousekeepingLeuchtfeuerIntegration::class)
->tag('mautic.integration')
->tag('mautic.basic_integration');
$services->get(\MauticPlugin\LeuchtfeuerHousekeepingBundle\Integration\Support\ConfigSupport::class)
->tag('mautic.config_integration');

$services->alias('mautic.integration.housekeepingleuchtfeuer', \MauticPlugin\LeuchtfeuerHousekeepingBundle\Integration\HousekeepingLeuchtfeuerIntegration::class);

$eventLogCleanup = $services->get(\MauticPlugin\LeuchtfeuerHousekeepingBundle\Service\EventLogCleanup::class);
$eventLogCleanup->arg('$dbPrefix', '%mautic.db_table_prefix%');
};
22 changes: 22 additions & 0 deletions DependencyInjection/LeuchtfeuerHousekeepingExtension.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

namespace MauticPlugin\LeuchtfeuerHousekeepingBundle\DependencyInjection;

use Symfony\Component\Config\FileLocator;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Extension\Extension;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;

class LeuchtfeuerHousekeepingExtension extends Extension
{
/**
* @param mixed[] $configs
*/
public function load(array $configs, ContainerBuilder $container): void
{
$loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../Config'));
$loader->load('services.php');
}
}
9 changes: 9 additions & 0 deletions Service/EventLogCleanup.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class EventLogCleanup
public const EMAIL_STATS = 'email_stats';
public const EMAIL_STATS_TOKENS = 'email_stats_tokens';
private const EMAIL_STATS_DEVICES = 'email_stats_devices';
public const PAGE_HITS = 'page_hits';

/**
* @var array<string, string>
Expand All @@ -37,6 +38,7 @@ class EventLogCleanup
self::EMAIL_STATS => self::PREFIX.'email_stats LEFT JOIN '.self::PREFIX.'emails ON '.self::PREFIX.'email_stats.email_id = '.self::PREFIX.'emails.id WHERE ('.self::PREFIX.'emails.is_published = 0 OR '.self::PREFIX.'emails.publish_down < DATE_SUB(NOW(),INTERVAL :daysOld DAY) OR '.self::PREFIX.'email_stats.email_id IS NULL) AND '.self::PREFIX.'email_stats.date_sent < DATE_SUB(NOW(),INTERVAL :daysOld DAY)',
self::EMAIL_STATS_TOKENS => self::PREFIX.'email_stats '.self::SET.' WHERE date_sent < DATE_SUB(NOW(),INTERVAL :daysOld DAY) AND tokens IS NOT NULL',
self::EMAIL_STATS_DEVICES => self::PREFIX.'email_stats_devices WHERE '.self::PREFIX.'email_stats_devices.date_opened < DATE_SUB(NOW(),INTERVAL :daysOld DAY)',
self::PAGE_HITS => self::PREFIX.'page_hits WHERE date_hit < DATE_SUB(NOW(),INTERVAL :daysOld DAY)',
];

private array $update = [
Expand All @@ -59,6 +61,9 @@ class EventLogCleanup
self::EMAIL_STATS_DEVICES => [
'daysOld' => self::DEFAULT_DAYS,
],
self::PAGE_HITS => [
'daysOld' => self::DEFAULT_DAYS,
],
];

private array $types = [
Expand All @@ -77,6 +82,9 @@ class EventLogCleanup
self::EMAIL_STATS_DEVICES => [
'daysOld' => \PDO::PARAM_INT,
],
self::PAGE_HITS => [
'daysOld' => \PDO::PARAM_INT,
],
];

private string $dryRunMessage = ' This is a dry run.';
Expand Down Expand Up @@ -125,6 +133,7 @@ public function deleteEventLogEntries(int $daysOld, ?int $campaignId, bool $dryR
self::EMAIL_STATS => 0,
self::EMAIL_STATS_TOKENS => 0,
self::EMAIL_STATS_DEVICES => 0,
self::PAGE_HITS => 0,
];

$this->connection->beginTransaction();
Expand Down
42 changes: 34 additions & 8 deletions Tests/Service/EventLogCleanupTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace MauticPlugin\LeuchtfeuerHousekeepingBundle\Tests\Service;

use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\Result;
use Doctrine\DBAL\Result;
use Generator;
use MauticPlugin\LeuchtfeuerHousekeepingBundle\Integration\Config;
use MauticPlugin\LeuchtfeuerHousekeepingBundle\Service\EventLogCleanup;
Expand All @@ -32,8 +32,18 @@ public function testDeleteEventLogEntries(array $operations, array $queries, arr
$connection = $this->createMock(Connection::class);
$connection->expects(self::exactly(count($queries)))
->method('executeQuery')
->withConsecutive(...$queries)
->willReturnOnConsecutiveCalls(...$statements);
->willReturnCallback(static function (string $sql, array $params, array $types) use (&$queries, &$statements): Result {
self::assertCount(count($queries), $statements);
$query = array_shift($queries);
$statement = array_shift($statements);

self::assertCount(3, $query);
self::assertSame($sql, $query[0]);
self::assertSame($params, $query[1]);
self::assertSame($types, $query[2]);

return $statement;
});

$loggedQueries = [];
foreach ($queries as $query) {
Expand All @@ -46,7 +56,11 @@ public function testDeleteEventLogEntries(array $operations, array $queries, arr
->willReturn(true);
$output->expects(self::exactly(count($queries)))
->method('writeln')
->withConsecutive(...$loggedQueries);
->willReturnCallback(static function (string $loggedQuery) use (&$loggedQueries): void {
$expected = array_shift($loggedQueries);
self::assertCount(1, $expected);
self::assertSame($loggedQuery, $expected[0]);
});

$config = $this->createMock(Config::class);
$config->method('isPublished')
Expand All @@ -66,6 +80,7 @@ public function runProvider(): Generator
EventLogCleanup::CAMPAIGN_LEAD_EVENTS => true,
EventLogCleanup::EMAIL_STATS => true,
EventLogCleanup::EMAIL_STATS_TOKENS => true,
EventLogCleanup::PAGE_HITS => true,
],
[
[
Expand All @@ -83,6 +98,11 @@ public function runProvider(): Generator
['daysOld' => $daysOld],
['daysOld' => \PDO::PARAM_INT],
],
[
'SELECT COUNT(1) as cnt FROM prefix_table_page_hits WHERE date_hit < DATE_SUB(NOW(),INTERVAL :daysOld DAY)',
['daysOld' => $daysOld],
['daysOld' => \PDO::PARAM_INT],
],
[
'SELECT COUNT(1) as cnt FROM prefix_table_email_stats_devices WHERE prefix_table_email_stats_devices.date_opened < DATE_SUB(NOW(),INTERVAL :daysOld DAY)',
['daysOld' => $daysOld],
Expand All @@ -94,8 +114,8 @@ public function runProvider(): Generator
['daysOld' => \PDO::PARAM_INT],
],
],
[3, 14, 23, 55, 57],
'3 lead_event_log, 14 campaign_lead_event_log, 55 email_stats_devices and 57 email_stats rows would have been deleted. 23 email_stats_tokens will be set to NULL. This is a dry run.',
[3, 14, 23, 4, 55, 57],
'3 lead_event_log, 14 campaign_lead_event_log, 4 page_hits, 55 email_stats_devices and 57 email_stats rows would have been deleted. 23 email_stats_tokens will be set to NULL. This is a dry run.',
true,
null,
];
Expand Down Expand Up @@ -216,6 +236,7 @@ public function runProvider(): Generator
EventLogCleanup::CAMPAIGN_LEAD_EVENTS => true,
EventLogCleanup::EMAIL_STATS => true,
EventLogCleanup::EMAIL_STATS_TOKENS => true,
EventLogCleanup::PAGE_HITS => true,
],
[
[
Expand All @@ -233,6 +254,11 @@ public function runProvider(): Generator
['daysOld' => $daysOld],
['daysOld' => \PDO::PARAM_INT],
],
[
'DELETE prefix_table_page_hits FROM prefix_table_page_hits WHERE date_hit < DATE_SUB(NOW(),INTERVAL :daysOld DAY)',
['daysOld' => $daysOld],
['daysOld' => \PDO::PARAM_INT],
],
[
'DELETE prefix_table_email_stats_devices FROM prefix_table_email_stats_devices WHERE prefix_table_email_stats_devices.date_opened < DATE_SUB(NOW(),INTERVAL :daysOld DAY)',
['daysOld' => $daysOld],
Expand All @@ -244,8 +270,8 @@ public function runProvider(): Generator
['daysOld' => \PDO::PARAM_INT],
],
],
[3, 14, 32, 55, 41],
'3 lead_event_log, 14 campaign_lead_event_log, 55 email_stats_devices and 41 email_stats rows have been deleted. 32 email_stats_tokens have been set to NULL.',
[3, 14, 32, 21, 55, 41],
'3 lead_event_log, 14 campaign_lead_event_log, 21 page_hits, 55 email_stats_devices and 41 email_stats rows have been deleted. 32 email_stats_tokens have been set to NULL.',
false,
null,
];
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
}
],
"scripts": {
"cs-fix": "./vendor/bin/php-cs-fixer fix --config .php-cs-fixer.php --using-cache no --show-progress dots -v"
"fixcs": "./vendor/bin/php-cs-fixer fix --config .php-cs-fixer.php --using-cache no --show-progress dots -v"
},
"config": {
"allow-plugins": {
Expand Down

0 comments on commit bf6947d

Please sign in to comment.