From 75cedc6df4797f2e2f90f06222ec5e5018fc0826 Mon Sep 17 00:00:00 2001
From: Elmar Ludwig <elmar.ludwig@uni-osnabrueck.de>
Date: Fri, 18 Aug 2023 09:59:48 +0000
Subject: [PATCH] add a new API to count pending migrations, fixes #3069

Closes #3069 and #3022

Merge request studip/studip!2046
---
 cli/Commands/Plugins/PluginInfo.php      |  2 +-
 lib/classes/PluginAdministration.php     |  2 +-
 lib/migrations/Migrator.php              | 19 +++++++++++++++++++
 lib/seminar_open.php                     |  4 +---
 tests/unit/lib/classes/MigrationTest.php |  4 ++--
 5 files changed, 24 insertions(+), 7 deletions(-)

diff --git a/cli/Commands/Plugins/PluginInfo.php b/cli/Commands/Plugins/PluginInfo.php
index e1b00f48e52..9809b138aa9 100644
--- a/cli/Commands/Plugins/PluginInfo.php
+++ b/cli/Commands/Plugins/PluginInfo.php
@@ -43,7 +43,7 @@ class PluginInfo extends AbstractPluginCommand
             if (is_dir($plugindir . '/migrations')) {
                 $schemaVersion = new \DBSchemaVersion($plugin['name']);
                 $migrator = new \Migrator($plugindir . '/migrations', $schemaVersion);
-                $plugin['pending_migrations'] = count($migrator->relevantMigrations(null));
+                $plugin['pending_migrations'] = $migrator->pendingMigrations();
                 $plugin['schema_version'] = $schemaVersion->get();
             }
 
diff --git a/lib/classes/PluginAdministration.php b/lib/classes/PluginAdministration.php
index 763f67dca3d..2732f58e6f8 100644
--- a/lib/classes/PluginAdministration.php
+++ b/lib/classes/PluginAdministration.php
@@ -364,7 +364,7 @@ class PluginAdministration
             if (is_dir($plugindir . '/migrations')) {
                 $schema_version = new DBSchemaVersion($plugin['name']);
                 $migrator = new Migrator($plugindir . '/migrations', $schema_version);
-                $info[$id]['pending_migrations'] = count($migrator->relevantMigrations(null));
+                $info[$id]['pending_migrations'] = $migrator->pendingMigrations();
                 $info[$id]['schema_version'] = $schema_version->get();
             }
         }
diff --git a/lib/migrations/Migrator.php b/lib/migrations/Migrator.php
index 07caa90baa6..50c8f3fe0cd 100644
--- a/lib/migrations/Migrator.php
+++ b/lib/migrations/Migrator.php
@@ -469,6 +469,25 @@ class Migrator
         return $all_branches ? $versions : $versions[$this->schema_version->getBranch()];
     }
 
+    /**
+     * Returns the number of available, but not yet applied migrations.
+     *
+     * @return int  migration count
+     */
+    public function pendingMigrations()
+    {
+        $pending = 0;
+
+        foreach (array_keys($this->migrationClasses()) as $version) {
+            list($branch, $version) = $this->migrationBranchAndVersion($version);
+            if ($this->schema_version->get($branch) < $version) {
+                ++$pending;
+            }
+        }
+
+        return $pending;
+    }
+
     /**
      * Overridable method used to return a textual representation of what's going
      * on in me. You can use me as you would use printf.
diff --git a/lib/seminar_open.php b/lib/seminar_open.php
index 33436d490d2..e79d39c5645 100644
--- a/lib/seminar_open.php
+++ b/lib/seminar_open.php
@@ -161,12 +161,10 @@ if (!Request::isXhr() && $perm->have_perm('root')) {
             new DBSchemaVersion('studip')
         );
 
-        $migrations = $migrator->relevantMigrations(null);
-
         $_SESSION['migration-check'] = [
             'disabled'  => $_SESSION['migration-check']['disabled'] ?? false,
             'timestamp' => time(),
-            'count'     => count($migrations),
+            'count'     => $migrator->pendingMigrations()
         ];
     }
 
diff --git a/tests/unit/lib/classes/MigrationTest.php b/tests/unit/lib/classes/MigrationTest.php
index 0aabbcd42c6..dd78ac7ed7d 100644
--- a/tests/unit/lib/classes/MigrationTest.php
+++ b/tests/unit/lib/classes/MigrationTest.php
@@ -95,7 +95,7 @@ class MigrationTest extends \Codeception\Test\Unit
         $migrator = $this->getMigrator($schema_version);
         $migrator->migrateTo(null);
         $this->assertSame(10, $schema_version->get());
-        $this->assertSame(0, count($migrator->relevantMigrations(null)));
+        $this->assertSame(0, $migrator->pendingMigrations());
 
         return $schema_version;
     }
@@ -108,7 +108,7 @@ class MigrationTest extends \Codeception\Test\Unit
         $migrator = $this->getMigrator($schema_version);
         $migrator->migrateTo(0);
         $this->assertSame(0, $schema_version->get());
-        $this->assertSame(4, count($migrator->relevantMigrations(null)));
+        $this->assertSame(4, $migrator->pendingMigrations());
     }
 
     public function testGaps()
-- 
GitLab