Skip to content
Merged
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
67 changes: 67 additions & 0 deletions Classes/Command/OrderItemCleanupCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<?php

declare(strict_types=1);

namespace Extcode\Cart\Command;

/*
* This file is part of the package extcode/cart.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

use DateTimeImmutable;
use Extcode\Cart\Service\OrderItemCleanupService;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use TYPO3\CMS\Core\Core\Bootstrap;

class OrderItemCleanupCommand extends Command
{
public function __construct(
private readonly OrderItemCleanupService $orderItemCleanupService,
) {
parent::__construct();
}

protected function configure()
{
$this->setDescription('Will remove all old orders');
$this->addArgument(
'cutOffDate',
InputArgument::REQUIRED,
'cutOffDate'
);
}

protected function execute(InputInterface $input, OutputInterface $output): int
{
$cutOffDate = $input->getArgument('cutOffDate');

if (is_string($cutOffDate) === false || $this->isCutOffDateValid($cutOffDate) === false) {
$output->writeln('The cutOffDate argument must follow the pattern YYYY-MM-DD.');

return Command::FAILURE;
}

Bootstrap::initializeBackendAuthentication();

$this->orderItemCleanupService->run(
new DateTimeImmutable(
$cutOffDate
)
);

return Command::SUCCESS;
}

private function isCutOffDateValid(string $cutOffDate): bool
{
$pattern = '/^\d{4}-\d{2}-\d{2}$/';

return preg_match($pattern, $cutOffDate) === 1;
}
}
82 changes: 82 additions & 0 deletions Classes/Service/OrderItemCleanupService.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
<?php

declare(strict_types=1);

namespace Extcode\Cart\Service;

/*
* This file is part of the package extcode/cart.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

use DateTimeImmutable;
use Extcode\Cart\Utility\Typo3GlobalsUtility;
use RuntimeException;
use TYPO3\CMS\Core\Database\Connection;
use TYPO3\CMS\Core\Database\ConnectionPool;
use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Utility\GeneralUtility;

final readonly class OrderItemCleanupService
{
public function __construct(
private ConnectionPool $connectionPool,
) {}

public function run(DateTimeImmutable $cutOffDate): void
{
$this->deleteRecordsFromTable(
'tx_cart_domain_model_order_item',
$this->getRecordUidsToDelete(
'tx_cart_domain_model_order_item',
$cutOffDate
)
);
}

private function getRecordUidsToDelete(string $tableName, DateTimeImmutable $cutOffDate): array
{
$queryBuilder = $this->connectionPool->getQueryBuilderForTable($tableName);
$queryBuilder
->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class));

return $queryBuilder
->select('uid')
->from($tableName)
->where(
$queryBuilder->expr()->lt(
'crdate',
$queryBuilder->createNamedParameter($cutOffDate->getTimestamp(), Connection::PARAM_INT)
),
)
->executeQuery()
->fetchFirstColumn();
}

private function deleteRecordsFromTable(string $tableName, array $recordUids): void
{
$dataHandler = GeneralUtility::makeInstance(DataHandler::class);
$dataHandler->start(
[],
[
$tableName => array_fill_keys($recordUids, [
'delete' => 1,
]),
],
Typo3GlobalsUtility::getTypo3BackendUser()
);
$dataHandler->process_cmdmap();

if ($dataHandler->errorLog !== []) {
throw new RuntimeException(
'Could not properly delete records for table: ' . $tableName . ', got the following errors: ' . implode(', ', $dataHandler->errorLog),
1751526777
);
}
}
}
29 changes: 29 additions & 0 deletions Classes/Utility/Typo3GlobalsUtility.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<?php

declare(strict_types=1);

namespace Extcode\Cart\Utility;

/*
* This file is part of the package extcode/cart.
*
* For the full copyright and license information, please read the
* LICENSE file that was distributed with this source code.
*/

use TypeError;
use TYPO3\CMS\Core\Authentication\BackendUserAuthentication;

final readonly class Typo3GlobalsUtility
{
public static function getTypo3BackendUser(): BackendUserAuthentication
{
$user = $GLOBALS['BE_USER'] ?? null;

if (!$user instanceof BackendUserAuthentication) {
throw new TypeError('Globals BE_USER was not of type BackendUserAuthentication, got: ' . $user, 1769004660);
}

return $user;
}
}
4 changes: 2 additions & 2 deletions Configuration/Backend/Modules.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
],
'extensionName' => 'Cart',
'iconIdentifier' => 'ext-cart-module',
'navigationComponent' => '@typo3/backend/page-tree/page-tree-element',
'navigationComponent' => '@typo3/backend/tree/page-tree-element',
],
'cart_cart_orders' => [
'parent' => 'cart_cart_main',
Expand All @@ -41,6 +41,6 @@
DocumentController::class => 'download, create',
],
'iconIdentifier' => 'ext-cart-module-order',
'navigationComponent' => '@typo3/backend/page-tree/page-tree-element',
'navigationComponent' => '@typo3/backend/tree/page-tree-element',
],
];
2 changes: 2 additions & 0 deletions Configuration/Services.php
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@
$services->set('Extcode\Cart\Hooks\ItemsProcFunc')
->public();
}

$containerConfigurator->import('Services/ConsoleCommands.php');
};
4 changes: 3 additions & 1 deletion Configuration/Services.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,9 @@ services:

Extcode\Cart\:
resource: '../Classes/*'
exclude: '../Classes/Widgets/*'
exclude:
- '../Classes/Widgets/*'
- '../Classes/Command/*'

Extcode\Cart\EventListener\Template\Components\ModifyButtonBar:
tags:
Expand Down
25 changes: 25 additions & 0 deletions Configuration/Services/ConsoleCommands.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

use Extcode\Cart\Command\OrderItemCleanupCommand;
use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator;

return static function (ContainerConfigurator $containerConfigurator) {
$services = $containerConfigurator
->services()
->defaults()
->autowire()
->autoconfigure()
;

$services
->set(OrderItemCleanupCommand::class)
->tag(
'console.command',
[
'command' => 'order:cleanup',
]
)
;
};
32 changes: 32 additions & 0 deletions Documentation/Administrator/Commands/Index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
.. include:: ../../Includes.rst.txt

========
Commands
========

order:cleanup
=============

The order:cleanup command requires the date before which all orders are to be
set to deleted (cutOffDate) as an argument. The format for this date only
accepts the format YYYY-MM-DD.

.. code-block:: bash

# Remove all orders created before 1st January 2025
vendor/bin/typo3 order:cleanup 2025-01-01

The DataHandler is then used to process all orders before this date.

.. IMPORTANT::
Orders are only set to deleted, but not removed from the database. The
database must be cleaned up afterwards using `vendor/bin/typo3 cleanup:deletedrecords`.

Restrictions:
No special cases such as belonging to a frontend user are taken into account.
There is no interaction with the user of the command.
No execution via the scheduler is planned.

.. WARNING::
No Backup?
No Mercy!
1 change: 1 addition & 0 deletions Documentation/Administrator/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ Information for the installation and configuration of the extension.

Installation/Index
Configuration/Index
Commands/Index
OtherCartExtensions/Index
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
.. include:: ../../Includes.rst.txt

==============================================
Feature: #730 - Add order item cleanup command
==============================================

See `Issue 730 <https://github.com/extcode/cart/issues/638>`__

Description
===========

After a while, more and more orders will clutter up the database. Depending on
the shop, it may no longer be possible to delete them manually.

A cleanup command should ensure that older orders created before a certain date
can be deleted automatically.

Among other things, this serves to conserve data. As a rule, older orders are no
longer needed on the website for further processing, unless you save the orders
for a front-end user and want to keep them available in the account for a long
time.

The first version should:

- use the DataHandler to set orders to be deleted
- ignore special cases such as those associated with a frontend user
- have no interaction with the user of the command
- not allow execution via the scheduler

The user of the command should create a backup of the database beforehand.
The database must be cleaned up afterwards using the
`vendor/bin/typo3 cleanup:deletedrecords`, as the command only sets orders
deleted flag to true, but does not remove them.

Impact
======

No direct impact.

.. index:: API
20 changes: 20 additions & 0 deletions Documentation/Changelog/11.7/Index.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
.. include:: ../../Includes.rst.txt

11.7 Changes
============

**Table of contents**

.. contents::
:local:
:depth: 1

Features
--------

.. toctree::
:maxdepth: 1
:titlesonly:
:glob:

Feature-*
1 change: 1 addition & 0 deletions Documentation/Changelog/Index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ ChangeLog
:maxdepth: 5
:titlesonly:

11.7/Index
11.3/Index
11.1/Index
11.0/Index
Expand Down
4 changes: 2 additions & 2 deletions Documentation/guides.xml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@
interlink-shortcode="extcode/cart"
/>
<project title="Cart"
release="11.6.0"
version="11.6"
release="11.7.0"
version="11.7"
copyright="2018 - 2025"
/>
<inventory id="t3tsref" url="https://docs.typo3.org/typo3cms/TyposcriptReference/"/>
Expand Down
Loading