Skip to content

Commit 1ec8fab

Browse files
committed
Merge branch 'release/1.10.50'
2 parents c2560d4 + 7d7d30e commit 1ec8fab

File tree

7 files changed

+74
-8
lines changed

7 files changed

+74
-8
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
1. [](#bugfix)
1111
* Fix for deeply nested sortable fields (at last!)
1212
* Restore admin session timeout modal by returning 401 for timed-out AJAX requests
13+
* Honor `system.updates.safe_upgrade` so legacy Grav installs keep the classic updater
1314

1415
# v1.10.49.1
1516
## 09/03/2025

admin.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -385,6 +385,11 @@ public function onAdminTools(Event $event)
385385
'direct-install' => [['admin.super'], 'PLUGIN_ADMIN.DIRECT_INSTALL'],
386386
]);
387387

388+
$config = $this->grav['config'] ?? null;
389+
if (!SafeUpgradeManager::configAllowsSafeUpgrade($config)) {
390+
return;
391+
}
392+
388393
try {
389394
$manifestFiles = glob(GRAV_ROOT . '/user/data/upgrades/*.json') ?: [];
390395

classes/plugin/SafeUpgradeManager.php

Lines changed: 43 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515
namespace Grav\Plugin\Admin;
1616

17+
use Grav\Common\Config\Config;
1718
use Grav\Common\Filesystem\Folder;
1819
use Grav\Common\GPM\Installer;
1920
use Grav\Common\GPM\GPM;
@@ -178,6 +179,14 @@ public function hasSnapshots(): bool
178179
*/
179180
public function restoreSnapshot(string $snapshotId): array
180181
{
182+
if (!$this->isSafeUpgradeEnabled()) {
183+
return [
184+
'status' => 'error',
185+
'message' => 'Safe upgrade is disabled in configuration.',
186+
'manifest' => null,
187+
];
188+
}
189+
181190
try {
182191
$safeUpgrade = $this->getSafeUpgradeService();
183192
$manifest = $safeUpgrade->rollback($snapshotId);
@@ -934,6 +943,12 @@ public function runRestore(array $options): array
934943

935944
public function runSnapshot(array $options): array
936945
{
946+
if (!$this->isSafeUpgradeEnabled()) {
947+
return $this->errorResult('Safe upgrade is disabled in configuration.', [
948+
'operation' => 'snapshot'
949+
]);
950+
}
951+
937952
$label = isset($options['label']) ? (string)$options['label'] : null;
938953
if ($label !== null) {
939954
$label = trim($label);
@@ -1068,14 +1083,37 @@ protected function isSafeUpgradeEnabled(): bool
10681083
{
10691084
try {
10701085
$config = $this->grav['config'] ?? null;
1071-
if ($config === null) {
1072-
return true;
1086+
return self::configAllowsSafeUpgrade($config);
1087+
} catch (Throwable $e) {
1088+
return false;
1089+
}
1090+
}
1091+
1092+
/**
1093+
* @param Config|null $config
1094+
* @return bool
1095+
*/
1096+
public static function configAllowsSafeUpgrade(?Config $config): bool
1097+
{
1098+
if ($config === null) {
1099+
return false;
1100+
}
1101+
1102+
$value = $config->get('system.updates.safe_upgrade');
1103+
if ($value === null) {
1104+
return false;
1105+
}
1106+
1107+
if (is_string($value)) {
1108+
$filtered = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);
1109+
if ($filtered === null) {
1110+
return false;
10731111
}
10741112

1075-
return (bool)$config->get('system.updates.safe_upgrade', true);
1076-
} catch (Throwable $e) {
1077-
return true;
1113+
return $filtered;
10781114
}
1115+
1116+
return (bool)$value;
10791117
}
10801118

10811119
/**

themes/grav/app/updates/index.js

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,14 @@ import './update';
1010
import './channel-switcher';
1111
import SafeUpgrade from './safe-upgrade';
1212

13+
const SAFE_UPGRADE_ENABLED = Number(config.safe_upgrade_enabled || 0) === 1;
14+
1315
export default class Updates {
1416
constructor(payload = {}) {
1517
this.setPayload(payload);
1618
this.task = `task${config.param_sep}`;
1719
this.updateURL = '';
18-
this.safeUpgrade = new SafeUpgrade(this);
20+
this.safeUpgrade = SAFE_UPGRADE_ENABLED ? new SafeUpgrade(this) : null;
1921
}
2022

2123
setPayload(payload = {}) {

themes/grav/js/admin.min.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3055,14 +3055,15 @@ function updates_toPrimitive(t, r) { if ("object" != updates_typeof(t) || !t) re
30553055

30563056

30573057

3058+
var SAFE_UPGRADE_ENABLED = Number(external_GravAdmin_namespaceObject.config.safe_upgrade_enabled || 0) === 1;
30583059
var Updates = /*#__PURE__*/function () {
30593060
function Updates() {
30603061
var payload = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
30613062
updates_classCallCheck(this, Updates);
30623063
this.setPayload(payload);
30633064
this.task = "task".concat(external_GravAdmin_namespaceObject.config.param_sep);
30643065
this.updateURL = '';
3065-
this.safeUpgrade = new SafeUpgrade(this);
3066+
this.safeUpgrade = SAFE_UPGRADE_ENABLED ? new SafeUpgrade(this) : null;
30663067
}
30673068
return updates_createClass(Updates, [{
30683069
key: "setPayload",

themes/grav/templates/partials/base-root.html.twig

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,8 @@
8282
</div>
8383
{% endblock %}
8484

85-
{% block modals %}
85+
{% set safe_upgrade_enabled = config.system.updates.safe_upgrade|default(false) %}
86+
{% block modals %}
8687
{# Session expired blocking modal #}
8788
<div class="remodal" data-remodal-id="session-expired" data-remodal-options="hashTracking: false">
8889
<form>
@@ -127,6 +128,7 @@
127128
</div>
128129
</form>
129130
</div>
131+
{% if safe_upgrade_enabled %}
130132
<div class="remodal safe-upgrade-modal" data-remodal-id="update-grav" data-remodal-options="hashTracking: false">
131133
<form class="safe-upgrade-form">
132134
<div class="safe-upgrade-header">
@@ -146,6 +148,21 @@
146148
</div>
147149
</form>
148150
</div>
151+
{% else %}
152+
<div class="remodal" data-remodal-id="update-grav" data-remodal-options="hashTracking: false">
153+
<form>
154+
<h1>{{ "PLUGIN_ADMIN.MODAL_DELETE_FILE_CONFIRMATION_REQUIRED_TITLE"|t }}</h1>
155+
<p class="bigger">
156+
{{ "PLUGIN_ADMIN.MODAL_UPDATE_GRAV_CONFIRMATION_REQUIRED_DESC"|t }}
157+
</p>
158+
<br>
159+
<div class="button-bar">
160+
<button data-remodal-action="cancel" class="button secondary remodal-cancel"><i class="fa fa-fw fa-close"></i> {{ "PLUGIN_ADMIN.CANCEL"|t }}</button>
161+
<button data-remodal-action="confirm" class="button remodal-confirm disable-after-click"><i class="fa fa-fw fa-check"></i> {{ "PLUGIN_ADMIN.CONTINUE"|t }}</button>
162+
</div>
163+
</form>
164+
</div>
165+
{% endif %}
149166
{% endblock %}
150167

151168
</main>

themes/grav/templates/partials/javascript-config.html.twig

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
{% set plugins_enabled = config.plugins.admin.notifications.plugins is same as(true) or config.plugins.admin.notifications.plugins == 'true' %}
55
{% set themes_enabled = config.plugins.admin.notifications.themes is same as(true) or config.plugins.admin.notifications.themes == 'true' %}
66
{% set notifications = (feed_enabled or dashboard_enabled or plugins_enabled or themes_enabled) ? 1 : 0 %}
7+
{% set safe_upgrade_enabled = config.system.updates.safe_upgrade|default(false) %}
78

89
{% switch template_route %}
910
{% case 'dashboard' %}
@@ -28,6 +29,7 @@
2829
{% endif %}
2930
admin_timeout: '{{ config.plugins.admin.session.timeout ?: 1800 }}',
3031
keep_alive_enabled: {{ (config.plugins.admin.session.keep_alive is defined ? config.plugins.admin.session.keep_alive : true) ? 1 : 0 }},
32+
safe_upgrade_enabled: {{ safe_upgrade_enabled ? 1 : 0 }},
3133
admin_nonce: '{{ admin.getNonce }}',
3234
language: '{{ grav.user.language|default('en') }}',
3335
pro_enabled: '{{ config.plugins["admin-pro"].enabled }}',

0 commit comments

Comments
 (0)