Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add symfony command to remove expired anonymous wishlists #256

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 11 additions & 0 deletions doc/01-installation.md
Original file line number Diff line number Diff line change
Expand Up @@ -111,3 +111,14 @@ framework:
```

All commands from the plugin implement the `WishlistSyncCommandInterface` interface, so there is no need for other configuration.

## Removing anonymous wishlists after expiration period

You can remove anonymous wishlists that have not been updated for a specified period of time. To do so, you need to add `bitbag:remove-anonymous-wishlists` Symfony console command to your cron jobs.

You can specify the expiration period in your parameters file to override the default value of 30 days:

```yaml
parameters:
bitbag_sylius_wishlist_plugin.parameters.anonymous_wishlist_expiration_period: 30 days # Remove all anonymous wishlists that were updated more than 30 days ago.
```
55 changes: 55 additions & 0 deletions src/Console/RemoveAnonymousWishlistsCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* You can find more information about us on https://bitbag.io and write us
* an email on [email protected].
*/

declare(strict_types=1);

namespace BitBag\SyliusWishlistPlugin\Console;

use BitBag\SyliusWishlistPlugin\Remover\AnonymousWishlistsRemoverInterface;
use SyliusLabs\Polyfill\Symfony\FrameworkBundle\Command\ContainerAwareCommand;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

/**
* @final
*/
class RemoveAnonymousWishlistsCommand extends ContainerAwareCommand
{
protected static $defaultName = 'bitbag:remove-anonymous-wishlists';

protected function configure(): void
{
$this
->setDescription('Removes anonymous wishlists that have been idle for a period set in `bitbag_sylius_wishlist_plugin.parameters.anonymous_wishlist_expiration_period` configuration key.')
;
}

protected function execute(InputInterface $input, OutputInterface $output)
{
/** @var string $expirationTime */
$expirationTime = $this->getContainer()->getParameter('bitbag_sylius_wishlist_plugin.parameters.anonymous_wishlist_expiration_period');

if (empty($expirationTime)) {
$output->writeln('<error>`bitbag_sylius_wishlist_plugin.parameters.anonymous_wishlist_expiration_period` configuration key is not set, so no wishlists will be removed.</error>');

return 0;
}

$output->writeln(sprintf(
'Command will remove anonymous wishlists that have been idle for <info>%s</info>.',
(string) $expirationTime,
));

/** @var AnonymousWishlistsRemoverInterface $anonymousWishlistsRemover */
$anonymousWishlistsRemover = $this->getContainer()->get('bitbag_sylius_wishlist_plugin.services.anonymous_wishlists_remover');
$anonymousWishlistsRemover->remove();

return 0;
}
}
1 change: 1 addition & 0 deletions src/DependencyInjection/BitBagSyliusWishlistExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ public function load(array $config, ContainerBuilder $container): void
$this->registerResources('bitbag_sylius_wishlist_plugin', 'doctrine/orm', $config['resources'], $container);
$loader->load('services.yml');
$container->setParameter('bitbag_sylius_wishlist_plugin.parameters.wishlist_cookie_token', $config['wishlist_cookie_token']);
$container->setParameter('bitbag_sylius_wishlist_plugin.parameters.anonymous_wishlist_expiration_period', $config['anonymous_wishlist_expiration_period']);
$container->setParameter('bitbag_sylius_wishlist_plugin.parameters.allowed_mime_types', $config['allowed_mime_types']);
}

Expand Down
13 changes: 13 additions & 0 deletions src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,19 @@ public function getConfigTreeBuilder(): TreeBuilder
})
->end()
->end()
->scalarNode('anonymous_wishlist_expiration_period')
->defaultValue('30 days')
->cannotBeEmpty()
->validate()
->always(function ($value) {
if (!is_string($value)) {
throw new InvalidConfigurationException('anonymous_wishlist_expiration_period must be string');
}

return $value;
})
->end()
->end()
->arrayNode('allowed_mime_types')
->defaultValue([
'text/csv',
Expand Down
32 changes: 32 additions & 0 deletions src/Remover/AnonymousWishlistsRemover.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* You can find more information about us on https://bitbag.io and write us
* an email on [email protected].
*/

declare(strict_types=1);

namespace BitBag\SyliusWishlistPlugin\Remover;

use BitBag\SyliusWishlistPlugin\Repository\WishlistRepositoryInterface;
use Doctrine\Persistence\ObjectManager;

final class AnonymousWishlistsRemover implements AnonymousWishlistsRemoverInterface
{
public function __construct(
private WishlistRepositoryInterface $wishlistRepository,
private ObjectManager $wishlistManager,
private ?string $expirationPeriod,
) {
}

public function remove(): void
{
$this->wishlistRepository->deleteAllAnonymousUntil(
new \DateTime('-' . $this->expirationPeriod),
);
}
}
17 changes: 17 additions & 0 deletions src/Remover/AnonymousWishlistsRemoverInterface.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

/*
* This file has been created by developers from BitBag.
* Feel free to contact us once you face any issues or want to start
* You can find more information about us on https://bitbag.io and write us
* an email on [email protected].
*/

declare(strict_types=1);

namespace BitBag\SyliusWishlistPlugin\Remover;

interface AnonymousWishlistsRemoverInterface
{
public function remove(): void;
}
12 changes: 12 additions & 0 deletions src/Repository/WishlistRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,4 +145,16 @@ public function findOneByShopUserAndName(ShopUserInterface $shopUser, string $na
->getOneOrNullResult()
;
}

public function deleteAllAnonymousUntil(\DateTime $until): int
{
return $this->createQueryBuilder('o')
->delete(WishlistInterface::class, 'o')
->where('o.shopUser IS NULL')
->andWhere('o.updatedAt < :until')
->setParameter('until', $until)
->getQuery()
->execute()
;
}
}
5 changes: 5 additions & 0 deletions src/Repository/WishlistRepositoryInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -40,4 +40,9 @@ public function findAllByAnonymousAndChannel(?string $token, ChannelInterface $c
public function findOneByTokenAndName(string $token, string $name): ?WishlistInterface;

public function findOneByShopUserAndName(ShopUserInterface $shopUser, string $name): ?WishlistInterface;

/**
* @return int Number of deleted wishlists.
*/
public function deleteAllAnonymousUntil(\DateTime $until): int;
}
13 changes: 13 additions & 0 deletions src/Resources/config/services.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ imports:
- { resource: "services/**/*.yml" }

services:
bitbag_sylius_wishlist_plugin.console.remove_anonymous_wishlists_command:
class: BitBag\SyliusWishlistPlugin\Console\RemoveAnonymousWishlistsCommand
tags:
- { name: console.command }

bitbag_sylius_wishlist_plugin.controller.action.base_wishlist_products_action:
abstract: true
class: BitBag\SyliusWishlistPlugin\Controller\Action\BaseWishlistProductsAction
Expand Down Expand Up @@ -348,6 +353,14 @@ services:
- '@request_stack'
- "@translator"

bitbag_sylius_wishlist_plugin.services.anonymous_wishlists_remover:
public: true
class: BitBag\SyliusWishlistPlugin\Remover\AnonymousWishlistsRemover
arguments:
- "@bitbag_sylius_wishlist_plugin.repository.wishlist"
- "@bitbag_sylius_wishlist_plugin.manager.wishlist"
- "%bitbag_sylius_wishlist_plugin.parameters.anonymous_wishlist_expiration_period%"

bitbag_sylius_wishlist_plugin.checker.wishlist_name_checker:
class: BitBag\SyliusWishlistPlugin\Checker\WishlistNameChecker

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
Sylius\Component\Locale\Model\Locale:
locale:
createdAt: '<dateTimeBetween("-200 days", "now")>'
code: 'en_US'
Sylius\Component\Currency\Model\Currency:
dollar:
code: 'USD'
Sylius\Component\Core\Model\Channel:
channel_us:
code: 'US'
name: 'name'
defaultLocale: '@locale'
locales: [ '@locale' ]
taxCalculationStrategy: 'order_items_based'
baseCurrency: '@dollar'
enabled: true
Sylius\Component\Core\Model\Customer:
customer_oliver:
firstName: 'John'
lastName: 'Nowak'
email: '[email protected]'
emailCanonical: '[email protected]'
Sylius\Component\Core\Model\ShopUser:
user_oliver:
plainPassword: '123password'
roles: [ 'ROLE_USER' ]
enabled: 'true'
customer: '@customer_oliver'
username: '[email protected]'
usernameCanonical: '[email protected]'
BitBag\SyliusWishlistPlugin\Entity\Wishlist:
wishlist_one:
name: 'Wishlist One'
channel: '@channel_us'
token: 'token'
updatedAt: '<date_create_from_format("Y-m-d H:i:s", "2023-01-01 00:00:00")>'
wishlist_two:
name: 'Wishlist Two'
channel: '@channel_us'
token: 'token'
updatedAt: '<date_create_from_format("Y-m-d H:i:s", "2024-01-02 00:00:00")>'
olivier_wishlist:
name: 'Olivier Wishlist'
shopUser: '@user_oliver'
channel: '@channel_us'
updatedAt: '<date_create_from_format("Y-m-d H:i:s", "2023-01-01 00:00:00")>'
16 changes: 16 additions & 0 deletions tests/Integration/Repository/WishlistRepositoryTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,20 @@ public function testItFindsOneWishlistByShopUserAndName(): void
$missingResult = $this->repository->findOneByShopUserAndName($shopUser, 'Bruce Wishlist');
$this->assertNull($missingResult);
}

public function testItDeleteAllAnonymousUntilWishlists(): void
{
$this->loadFixturesFromFile('test_it_delete_all_anonymous_until_wishlists.yaml');

/** @var int $result */
$result = $this->repository->deleteAllAnonymousUntil(new \DateTime('2024-01-01 00:00:00'));

$this->assertIsInt($result);
$this->assertSame(1, $result);

$wishlists = $this->repository->findAll();
$this->assertCount(2, $wishlists);
$this->assertSame('Wishlist Two', $wishlists[0]->getName());
$this->assertSame('Olivier Wishlist', $wishlists[1]->getName());
}
}