Add compatibility preflight to upgrade flow + compatibility badges

Gpm::upgradeGrav() now calls generatePreflightReport() from the new
package's Install.php before proceeding. If incompatible plugins are
detected, a detailed error message is shown listing which plugins need
to be disabled.

Adds colored compatibility badges (1.7 blue, 1.8 green) to:
- Plugin list, theme list, and plugin detail views
- SCSS badge styles (.gpm-compat-17, .gpm-compat-18, .gpm-compat-api)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Andy Miller
2026-04-02 10:26:58 -06:00
parent eb3cc2e9d1
commit 30a90cc69b
5 changed files with 60 additions and 0 deletions

View File

@@ -423,6 +423,25 @@ class Gpm
$script = $folder . '/system/install.php';
/** Install $installer */
if ((file_exists($script) && $install = include $script) && is_callable($install)) {
// Run preflight from the NEW package's installer if available
if (is_object($install) && method_exists($install, 'generatePreflightReport')) {
$report = $install->generatePreflightReport();
$blocking = $report['blocking'] ?? [];
$incompatible = $report['incompatible_packages'] ?? [];
if (!empty($blocking) || !empty($incompatible['blocking'])) {
$errors = [];
foreach ($blocking as $reason) {
$errors[] = $reason;
}
foreach ($incompatible['blocking'] ?? [] as $slug => $info) {
$errors[] = sprintf('<strong>%s</strong> (%s v%s) — not compatible with Grav %s. Disable it to proceed.',
$slug, $info['type'] ?? 'plugin', $info['version'] ?? '?', $incompatible['target'] ?? '?');
}
Installer::setError(implode('<br>', $errors));
return;
}
}
$install($zip);
} else {
Installer::install(

View File

@@ -84,6 +84,29 @@
line-height: 1.3;
}
.gpm-compat {
@extend .badge;
border-radius: 3px;
padding: 0 4px;
font-size: 0.75rem;
margin-left: 2px;
}
.gpm-compat-17 {
background: #3b82f6;
color: white;
}
.gpm-compat-18 {
background: #22c55e;
color: white;
}
.gpm-compat-api {
background: #06b6d4;
color: white;
}
.gpm-actions {
.enabled, .disabled {

View File

@@ -49,6 +49,18 @@
</tr>
{% endif %}
<tr>
<td>Compatibility:</td>
<td class="double">
{% set compat = plugin.compatibility.grav ?? ['1.7'] %}
{% if '1.7' in compat %}<span class="gpm-compat gpm-compat-17">1.7</span>{% endif %}
{% if '1.8' in compat %}<span class="gpm-compat gpm-compat-18">1.8</span>{% endif %}
{% if plugin.compatibility.api is defined %}
{% for v in plugin.compatibility.api %}<span class="gpm-compat gpm-compat-api">api:{{ v }}</span>{% endfor %}
{% endif %}
</td>
</tr>
{% if plugin.description %}
<tr>
<td>{{ "PLUGIN_ADMIN.DESCRIPTION"|t }}:</td>

View File

@@ -41,6 +41,9 @@
{% endif %}
<span class="gpm-version">v{{ plugin.version }}</span>
{% if isTestingRelease %}<span class="gpm-testing">test release</span>{% endif %}
{% set compat = plugin.compatibility.grav ?? ['1.7'] %}
{% if '1.7' in compat %}<span class="gpm-compat gpm-compat-17">1.7</span>{% endif %}
{% if '1.8' in compat %}<span class="gpm-compat gpm-compat-18">1.8</span>{% endif %}
</td>
<td class="gpm-actions">
{% if (not installing and (plugin.form.fields.enabled.type != 'hidden' and plugin.form.fields.tabs.fields.options.fields.enabled.type != 'hidden')) %}

View File

@@ -43,6 +43,9 @@
{% endif %}
<span class="gpm-version">v{{ theme.version }}</span>
{% if isTestingRelease %}<span class="gpm-testing">test release</span>{% endif %}
{% set compat = theme.compatibility.grav ?? ['1.7'] %}
{% if '1.7' in compat %}<span class="gpm-compat gpm-compat-17">1.7</span>{% endif %}
{% if '1.8' in compat %}<span class="gpm-compat gpm-compat-18">1.8</span>{% endif %}
</div>
<div class="gpm-screenshot">
{% set thumb = installing ? '//getgrav.org/images/' ~ theme.screenshot : theme.thumbnail %}