<?php declare(strict_types=1); /* * This file is part of contao-weinanlieferung-bundle. * * (c) vonRotenberg * * @license commercial */ namespace vonRotenberg\WeinanlieferungBundle\Migration; use Contao\CoreBundle\Migration\AbstractMigration; use Contao\CoreBundle\Migration\MigrationResult; use Doctrine\DBAL\Connection; use Doctrine\DBAL\Schema\Column; // only for type hints in comments class ReservationUnitFieldsMigration extends AbstractMigration { /** @var Connection */ private $db; public function __construct(Connection $db) { $this->db = $db; } public function shouldRun(): bool { $schemaManager = $this->db->createSchemaManager(); // If the database table itself does not exist we should do nothing if (!$schemaManager->tablesExist(['tl_vr_wa_reservation'])) { return false; } $columns = $schemaManager->listTableColumns('tl_vr_wa_reservation'); $missingUnitId = !isset($columns['unit_id']); $missingUnitAmount = !isset($columns['unit_amount']); // If either column is missing, we should run if ($missingUnitId || $missingUnitAmount) { return true; } // If both columns are present, check if we need to backfill data (legacy records) // We assume that if there exists any row where unit_amount = 0 AND behaelter > 0, we need to backfill. $needsBackfill = (bool) $this->db ->executeQuery('SELECT 1 FROM tl_vr_wa_reservation WHERE (unit_amount IS NULL OR unit_amount = 0) AND behaelter > 0 LIMIT 1') ->fetchOne(); return $needsBackfill; } public function run(): MigrationResult { $schemaManager = $this->db->createSchemaManager(); if (!$schemaManager->tablesExist(['tl_vr_wa_reservation'])) { return $this->createResult(true, 'Table tl_vr_wa_reservation does not exist, nothing to do.'); } $columns = $schemaManager->listTableColumns('tl_vr_wa_reservation'); $statements = []; if (!isset($columns['unit_id'])) { // As defined in DCA: int(10) unsigned NOT NULL default '0' $statements[] = "ALTER TABLE tl_vr_wa_reservation ADD unit_id INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER behaelter"; } if (!isset($columns['unit_amount'])) { // As defined in DCA: int(4) unsigned NOT NULL default 0 $statements[] = "ALTER TABLE tl_vr_wa_reservation ADD unit_amount INT(4) UNSIGNED NOT NULL DEFAULT 0 AFTER unit_id"; } foreach ($statements as $sql) { $this->db->executeStatement($sql); } // Backfill data for existing reservations: unit_amount = behaelter, unit_id = 0 // Only update rows where unit_amount is NULL or 0 to avoid overwriting already migrated data. $updated = $this->db->executeStatement( 'UPDATE tl_vr_wa_reservation SET unit_amount = behaelter, unit_id = 0 WHERE (unit_amount IS NULL OR unit_amount = 0)' ); $message = []; if (!empty($statements)) { $message[] = 'Added missing columns: ' . implode('; ', $statements); } $message[] = 'Backfilled reservations (rows updated): ' . $updated; return $this->createResult(true, implode(' | ', $message)); } }