Skip to content

Commit

Permalink
Merge pull request #52 from Setono/47-prune
Browse files Browse the repository at this point in the history
Add prune command
  • Loading branch information
loevgaard authored Sep 5, 2022
2 parents b0db26c + c0f295a commit 1e5f330
Show file tree
Hide file tree
Showing 15 changed files with 167 additions and 1 deletion.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@

/behat.yml
/phpspec.yml
/.phpunit.result.cache
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
"friendsofsymfony/oauth-server-bundle": ">2.0.0-alpha.0 ^2.0@dev",
"lexik/jwt-authentication-bundle": "^2.16",
"phpspec/phpspec": "^7.2",
"phpspec/prophecy-phpunit": "^2.0",
"phpunit/phpunit": "^9.5",
"polishsymfonycommunity/symfony-mocker-container": "^1.0",
"psalm/plugin-phpunit": "^0.17",
Expand Down
3 changes: 3 additions & 0 deletions src/Command/ProcessCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ class ProcessCommand extends Command
{
protected static $defaultName = 'setono:sylius-trustpilot:process';

/** @var string|null */
protected static $defaultDescription = 'Will start the processing of invitations';

private InvitationDispatcherInterface $invitationDispatcher;

public function __construct(
Expand Down
34 changes: 34 additions & 0 deletions src/Command/PruneCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusTrustpilotPlugin\Command;

use Setono\SyliusTrustpilotPlugin\Pruner\PrunerInterface;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

class PruneCommand extends Command
{
protected static $defaultName = 'setono:sylius-trustpilot:prune';

/** @var string|null */
protected static $defaultDescription = 'Will prune the invitations table';

private PrunerInterface $pruner;

public function __construct(PrunerInterface $pruner)
{
parent::__construct();

$this->pruner = $pruner;
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$this->pruner->prune();

return 0;
}
}
4 changes: 4 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ public function getConfigTreeBuilder(): TreeBuilder
->scalarNode('invitation_order_state')
->info('The state in which a order must be before an invitation based on this order is sent out')
->defaultValue(OrderInterface::STATE_FULFILLED)
->end()
->integerNode('prune_older_than')
->info('Prune invitations that are older than this number of minutes. Default: 30 days (30 * 24 * 60)')
->defaultValue(43_200) // 30 days
;

$this->addResourcesSection($rootNode);
Expand Down
3 changes: 2 additions & 1 deletion src/DependencyInjection/SetonoSyliusTrustpilotExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ public function load(array $configs, ContainerBuilder $container): void
/**
* @psalm-suppress PossiblyNullArgument
*
* @var array{driver: string, invitation_order_state: string, resources: array} $config
* @var array{driver: string, invitation_order_state: string, prune_older_than: int, resources: array} $config
*/
$config = $this->processConfiguration($this->getConfiguration([], $container), $configs);
$loader = new XmlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));

$container->setParameter('setono_sylius_trustpilot.invitation_order_state', $config['invitation_order_state']);
$container->setParameter('setono_sylius_trustpilot.prune_older_than', $config['prune_older_than']);

$this->registerResources('setono_sylius_trustpilot', $config['driver'], $config['resources'], $container);

Expand Down
28 changes: 28 additions & 0 deletions src/Pruner/Pruner.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusTrustpilotPlugin\Pruner;

use DateTimeImmutable;
use Setono\SyliusTrustpilotPlugin\Repository\InvitationRepositoryInterface;

final class Pruner implements PrunerInterface
{
private InvitationRepositoryInterface $invitationRepository;

private int $pruneOlderThan;

public function __construct(InvitationRepositoryInterface $invitationRepository, int $pruneOlderThan)
{
$this->invitationRepository = $invitationRepository;
$this->pruneOlderThan = $pruneOlderThan;
}

public function prune(): void
{
$this->invitationRepository->removeOlderThan(
new DateTimeImmutable(sprintf('-%d minutes', $this->pruneOlderThan))
);
}
}
13 changes: 13 additions & 0 deletions src/Pruner/PrunerInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusTrustpilotPlugin\Pruner;

interface PrunerInterface
{
/**
* Will prune invitations table
*/
public function prune(): void;
}
12 changes: 12 additions & 0 deletions src/Repository/InvitationRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Setono\SyliusTrustpilotPlugin\Repository;

use DateTimeInterface;
use Setono\SyliusTrustpilotPlugin\Model\InvitationInterface;
use Setono\SyliusTrustpilotPlugin\Workflow\InvitationWorkflow;
use Sylius\Bundle\ResourceBundle\Doctrine\ORM\EntityRepository;
Expand All @@ -30,4 +31,15 @@ public function findNew(string $orderState = OrderInterface::STATE_FULFILLED, in

return $objs;
}

public function removeOlderThan(DateTimeInterface $threshold): void
{
$this->createQueryBuilder('o')
->delete()
->andWhere('o.createdAt <= :threshold')
->setParameter('threshold', $threshold)
->getQuery()
->execute()
;
}
}
6 changes: 6 additions & 0 deletions src/Repository/InvitationRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace Setono\SyliusTrustpilotPlugin\Repository;

use DateTimeInterface;
use Setono\SyliusTrustpilotPlugin\Model\InvitationInterface;
use Sylius\Component\Order\Model\OrderInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
Expand All @@ -14,4 +15,9 @@ interface InvitationRepositoryInterface extends RepositoryInterface
* @return list<InvitationInterface>
*/
public function findNew(string $orderState = OrderInterface::STATE_FULFILLED, int $limit = 100): array;

/**
* Will remove invitations older than the given threshold
*/
public function removeOlderThan(DateTimeInterface $threshold): void;
}
1 change: 1 addition & 0 deletions src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -15,5 +15,6 @@
<import resource="services/menu.xml"/>
<import resource="services/message.xml"/>
<import resource="services/processor.xml"/>
<import resource="services/pruner.xml"/>
</imports>
</container>
7 changes: 7 additions & 0 deletions src/Resources/config/services/command.xml
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,12 @@

<tag name="console.command"/>
</service>

<service id="setono_sylius_trustpilot.command.prune"
class="Setono\SyliusTrustpilotPlugin\Command\PruneCommand">
<argument type="service" id="setono_sylius_trustpilot.pruner.default"/>

<tag name="console.command"/>
</service>
</services>
</container>
13 changes: 13 additions & 0 deletions src/Resources/config/services/pruner.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?xml version="1.0" encoding="UTF-8"?>

<container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="setono_sylius_trustpilot.pruner.default"
class="Setono\SyliusTrustpilotPlugin\Pruner\Pruner">
<argument type="service" id="setono_sylius_trustpilot.repository.invitation"/>
<argument>%setono_sylius_trustpilot.prune_older_than%</argument>
</service>
</services>
</container>
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
imports:
- { resource: "@SetonoSyliusTrustpilotPlugin/Resources/config/app/config.yaml" }

setono_sylius_trustpilot:
prune_older_than: 7200
39 changes: 39 additions & 0 deletions tests/Pruner/PrunerTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php

declare(strict_types=1);

namespace Tests\Setono\SyliusTrustpilotPlugin\Pruner;

use DateInterval;
use DateTimeImmutable;
use PHPUnit\Framework\TestCase;
use Prophecy\Argument;
use Prophecy\PhpUnit\ProphecyTrait;
use Setono\SyliusTrustpilotPlugin\Pruner\Pruner;
use Setono\SyliusTrustpilotPlugin\Repository\InvitationRepositoryInterface;

/**
* @covers \Setono\SyliusTrustpilotPlugin\Pruner\Pruner
*/
final class PrunerTest extends TestCase
{
use ProphecyTrait;

/**
* @test
*/
public function it_prunes(): void
{
$threshold = 43_200; // 30 days
$thresholdDateTime = (new DateTimeImmutable())->sub(new DateInterval(sprintf('PT%dM', $threshold)));
self::assertNotFalse($thresholdDateTime);

$repository = $this->prophesize(InvitationRepositoryInterface::class);
$repository->removeOlderThan(
Argument::which('getTimestamp', $thresholdDateTime->getTimestamp())
)->shouldBeCalled();

$pruner = new Pruner($repository->reveal(), $threshold);
$pruner->prune();
}
}

0 comments on commit 1e5f330

Please sign in to comment.