mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-07 18:44:08 +00:00
Add SavedExportOptionsMigrator for migrating export options
Introduced SavedExportOptionsMigrator to handle the migration of saved export options with structures ensuring versioning. Added unit tests to validate transformation logic and edge cases for better reliability.
This commit is contained in:
parent
bb30ddc876
commit
b5fd9cf4af
@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\MainBundle\Export\Migrator;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Service\RollingDate\RollingDate;
|
||||||
|
|
||||||
|
class SavedExportOptionsMigrator
|
||||||
|
{
|
||||||
|
public static function migrate(array $fromOptions): array
|
||||||
|
{
|
||||||
|
$to = [];
|
||||||
|
$to['aggregators'] = array_map(
|
||||||
|
self::mapEnabledStatus(...),
|
||||||
|
$fromOptions['export']['export']['aggregators'] ?? [],
|
||||||
|
);
|
||||||
|
|
||||||
|
$to['filters'] = array_map(
|
||||||
|
self::mapEnabledStatus(...),
|
||||||
|
$fromOptions['export']['export']['filters'] ?? [],
|
||||||
|
);
|
||||||
|
|
||||||
|
$to['export'] = [
|
||||||
|
'form' => array_map(
|
||||||
|
self::mapFormData(...),
|
||||||
|
array_filter(
|
||||||
|
$fromOptions['export']['export']['export'] ?? [],
|
||||||
|
static fn (string $key) => !in_array($key, ['filters', 'aggregators', 'pick_formatter'], true),
|
||||||
|
ARRAY_FILTER_USE_KEY,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
'version' => 1,
|
||||||
|
];
|
||||||
|
|
||||||
|
$to['pick_formatter'] = $fromOptions['export']['export']['pick_formatter']['alias'] ?? null;
|
||||||
|
$to['centers'] = [
|
||||||
|
'centers' => array_values(array_map(static fn ($id) => (int) $id, $fromOptions['centers']['centers']['c'] ?? $fromOptions['centers']['centers']['center'] ?? [])),
|
||||||
|
'regroupments' => array_values(array_map(static fn ($id) => (int) $id, $fromOptions['centers']['centers']['regroupment'] ?? [])),
|
||||||
|
];
|
||||||
|
$to['formatter'] = [
|
||||||
|
'form' => $fromOptions['formatter']['formatter'] ?? [],
|
||||||
|
'version' => 1,
|
||||||
|
];
|
||||||
|
|
||||||
|
return $to;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function mapEnabledStatus(array $modifiersData): array
|
||||||
|
{
|
||||||
|
if ('1' === ($modifiersData['enabled'] ?? '0')) {
|
||||||
|
return [
|
||||||
|
'form' => array_map(self::mapFormData(...), $modifiersData['form'] ?? []),
|
||||||
|
'version' => 1,
|
||||||
|
'enabled' => true,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
|
||||||
|
return ['enabled' => false];
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function mapFormData(array|string $formData): array|string|null
|
||||||
|
{
|
||||||
|
if (is_array($formData) && array_key_exists('roll', $formData)) {
|
||||||
|
return self::refactorRollingDate($formData);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (is_string($formData)) {
|
||||||
|
// we try different date formats
|
||||||
|
if (false !== \DateTimeImmutable::createFromFormat('d-m-Y', $formData)) {
|
||||||
|
return $formData;
|
||||||
|
}
|
||||||
|
if (false !== \DateTimeImmutable::createFromFormat('Y-m-d', $formData)) {
|
||||||
|
return $formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
// we try json content
|
||||||
|
try {
|
||||||
|
$data = json_decode($formData, true, 512, JSON_THROW_ON_ERROR);
|
||||||
|
|
||||||
|
if (is_array($data)) {
|
||||||
|
if (array_key_exists('type', $data) && array_key_exists('id', $data) && in_array($data['type'], ['person', 'thirdParty', 'user'], true)) {
|
||||||
|
return $data['id'];
|
||||||
|
}
|
||||||
|
$response = [];
|
||||||
|
foreach ($data as $item) {
|
||||||
|
if (array_key_exists('type', $item) && array_key_exists('id', $item) && in_array($item['type'], ['person', 'thirdParty', 'user'], true)) {
|
||||||
|
$response[] = $item['id'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ([] !== $response) {
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (\JsonException $e) {
|
||||||
|
return $formData;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return $formData;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static function refactorRollingDate(array $formData): ?array
|
||||||
|
{
|
||||||
|
if ('' === $formData['roll']) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
$fixedDate = null !== ($formData['fixedDate'] ?? null) ?
|
||||||
|
\DateTimeImmutable::createFromFormat('Y-m-d H:i:s', sprintf('%s 00:00:00', $formData['fixedDate']), new \DateTimeZone(date_default_timezone_get())) : null;
|
||||||
|
|
||||||
|
return (new RollingDate(
|
||||||
|
$formData['roll'],
|
||||||
|
$fixedDate,
|
||||||
|
))->normalize();
|
||||||
|
}
|
||||||
|
}
|
File diff suppressed because one or more lines are too long
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
declare(strict_types=1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Chill is a software for social workers
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view
|
||||||
|
* the LICENSE file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Chill\Migrations\Main;
|
||||||
|
|
||||||
|
use Chill\MainBundle\Export\Migrator\SavedExportOptionsMigrator;
|
||||||
|
use Doctrine\DBAL\Schema\Schema;
|
||||||
|
use Doctrine\DBAL\Types\Types;
|
||||||
|
use Doctrine\Migrations\AbstractMigration;
|
||||||
|
|
||||||
|
final class Version20250404123326 extends AbstractMigration
|
||||||
|
{
|
||||||
|
public function getDescription(): string
|
||||||
|
{
|
||||||
|
return 'Update option representation of saved exports';
|
||||||
|
}
|
||||||
|
|
||||||
|
public function up(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('ALTER TABLE chill_main_saved_export ADD COLUMN options_backup JSONB default \'[]\'');
|
||||||
|
$this->addSql('UPDATE chill_main_saved_export SET options_backup = options');
|
||||||
|
|
||||||
|
$result = $this->connection->executeQuery('SELECT id, options FROM chill_main_saved_export');
|
||||||
|
|
||||||
|
foreach ($result->iterateAssociative() as $row) {
|
||||||
|
$options = json_decode($row['options'], true, 512, JSON_THROW_ON_ERROR);
|
||||||
|
$this->addSql(
|
||||||
|
'UPDATE chill_main_saved_export SET options = :new_options WHERE id = :id',
|
||||||
|
['id' => $row['id'], 'new_options' => SavedExportOptionsMigrator::migrate($options)],
|
||||||
|
['id' => Types::STRING, 'new_options' => Types::JSON],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public function down(Schema $schema): void
|
||||||
|
{
|
||||||
|
$this->addSql('UPDATE chill_main_saved_export SET options = options_backup');
|
||||||
|
$this->addSql('ALTER TABLE chill_main_saved_export DROP COLUMN options_backup');
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user