Browse code

Add migration for the new introduced units

Benjamin Roth authored on02/09/2025 16:12:32
Showing1 changed files
1 1
new file mode 100644
... ...
@@ -0,0 +1,97 @@
1
+<?php
2
+
3
+declare(strict_types=1);
4
+
5
+/*
6
+ * This file is part of contao-weinanlieferung-bundle.
7
+ *
8
+ * (c) vonRotenberg
9
+ *
10
+ * @license commercial
11
+ */
12
+
13
+namespace vonRotenberg\WeinanlieferungBundle\Migration;
14
+
15
+use Contao\CoreBundle\Migration\AbstractMigration;
16
+use Contao\CoreBundle\Migration\MigrationResult;
17
+use Doctrine\DBAL\Connection;
18
+use Doctrine\DBAL\Schema\Column; // only for type hints in comments
19
+
20
+class ReservationUnitFieldsMigration extends AbstractMigration
21
+{
22
+    /** @var Connection */
23
+    private $db;
24
+
25
+    public function __construct(Connection $db)
26
+    {
27
+        $this->db = $db;
28
+    }
29
+
30
+    public function shouldRun(): bool
31
+    {
32
+        $schemaManager = $this->db->createSchemaManager();
33
+
34
+        // If the database table itself does not exist we should do nothing
35
+        if (!$schemaManager->tablesExist(['tl_vr_wa_reservation'])) {
36
+            return false;
37
+        }
38
+
39
+        $columns = $schemaManager->listTableColumns('tl_vr_wa_reservation');
40
+
41
+        $missingUnitId = !isset($columns['unit_id']);
42
+        $missingUnitAmount = !isset($columns['unit_amount']);
43
+
44
+        // If either column is missing, we should run
45
+        if ($missingUnitId || $missingUnitAmount) {
46
+            return true;
47
+        }
48
+
49
+        // If both columns are present, check if we need to backfill data (legacy records)
50
+        // We assume that if there exists any row where unit_amount = 0 AND behaelter > 0, we need to backfill.
51
+        $needsBackfill = (bool) $this->db
52
+            ->executeQuery('SELECT 1 FROM tl_vr_wa_reservation WHERE (unit_amount IS NULL OR unit_amount = 0) AND behaelter > 0 LIMIT 1')
53
+            ->fetchOne();
54
+
55
+        return $needsBackfill;
56
+    }
57
+
58
+    public function run(): MigrationResult
59
+    {
60
+        $schemaManager = $this->db->createSchemaManager();
61
+
62
+        if (!$schemaManager->tablesExist(['tl_vr_wa_reservation'])) {
63
+            return $this->createResult(true, 'Table tl_vr_wa_reservation does not exist, nothing to do.');
64
+        }
65
+
66
+        $columns = $schemaManager->listTableColumns('tl_vr_wa_reservation');
67
+        $statements = [];
68
+
69
+        if (!isset($columns['unit_id'])) {
70
+            // As defined in DCA: int(10) unsigned NOT NULL default '0'
71
+            $statements[] = "ALTER TABLE tl_vr_wa_reservation ADD unit_id INT(10) UNSIGNED NOT NULL DEFAULT '0' AFTER behaelter";
72
+        }
73
+
74
+        if (!isset($columns['unit_amount'])) {
75
+            // As defined in DCA: int(4) unsigned NOT NULL default 0
76
+            $statements[] = "ALTER TABLE tl_vr_wa_reservation ADD unit_amount INT(4) UNSIGNED NOT NULL DEFAULT 0 AFTER unit_id";
77
+        }
78
+
79
+        foreach ($statements as $sql) {
80
+            $this->db->executeStatement($sql);
81
+        }
82
+
83
+        // Backfill data for existing reservations: unit_amount = behaelter, unit_id = 0
84
+        // Only update rows where unit_amount is NULL or 0 to avoid overwriting already migrated data.
85
+        $updated = $this->db->executeStatement(
86
+            'UPDATE tl_vr_wa_reservation SET unit_amount = behaelter, unit_id = 0 WHERE (unit_amount IS NULL OR unit_amount = 0)'
87
+        );
88
+
89
+        $message = [];
90
+        if (!empty($statements)) {
91
+            $message[] = 'Added missing columns: ' . implode('; ', $statements);
92
+        }
93
+        $message[] = 'Backfilled reservations (rows updated): ' . $updated;
94
+
95
+        return $this->createResult(true, implode(' | ', $message));
96
+    }
97
+}