Skip to content

Commit ea5c1e9

Browse files
committed
fix: Handle missing table in DB repair — use activate() with dbDelta
The repair notice was showing indefinitely because: 1. is_database_schema_valid() checked only for a missing column, not a missing table — SHOW COLUMNS on a non-existent table returns empty, causing false positives 2. The repair handler called maybe_upgrade() which runs ALTER TABLE, which fails when the table itself doesn't exist Changes: - is_database_schema_valid() now checks SHOW TABLES first, then checks for the opt_in_token column - handle_database_upgrade() now calls MSKD_Activator::activate() which uses dbDelta to create missing tables and all their columns - Removed the direct ALTER TABLE fallback (wrong for missing tables) - Error notice now shows DB error and suggests deactivate/reactivate - Repair notice text updated to mention tables as well as columns
1 parent e8dfba3 commit ea5c1e9

2 files changed

Lines changed: 51 additions & 7 deletions

File tree

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
77

88
## [Unreleased]
99

10+
### Fixed
11+
- **Database repair notice persisting infinitely** — when clicking "Repair Database Now", if the required database table or column did not exist (or `ALTER TABLE` silently failed), the repair notice was shown on every page load indefinitely. The handler now calls `MSKD_Activator::activate()` (which uses `dbDelta` to create missing tables and columns), verifies the schema afterwards, and — if still failing — shows an actionable error notice with the database error message. The schema check also now correctly detects a missing table (not just a missing column).
12+
1013
### Changed
1114
- **Delete Inactive Subscribers button** now also deletes subscribers with `unsubscribed` status, in addition to `inactive` (unconfirmed). Updated button description, confirmation dialog, and success messages accordingly. Translations updated for Bulgarian and German.
1215

includes/Admin/class-admin-notices.php

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,29 @@ function () {
212212
);
213213
}
214214

215+
// Show error message if the database repair failed.
216+
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Just displaying a message.
217+
if ( isset( $_GET['mskd_db_error'] ) ) {
218+
// phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Just displaying a message.
219+
$db_error = sanitize_text_field( wp_unslash( $_GET['mskd_db_error'] ) );
220+
add_action(
221+
'admin_notices',
222+
function () use ( $db_error ) {
223+
?>
224+
<div class="notice notice-error">
225+
<p>
226+
<strong><?php esc_html_e( 'Mail System:', 'mail-system-by-katsarov-design' ); ?></strong>
227+
<?php esc_html_e( 'Database repair failed. One or more required tables or columns could not be created. Please deactivate and reactivate the plugin, or contact your hosting provider if the issue persists.', 'mail-system-by-katsarov-design' ); ?>
228+
</p>
229+
<?php if ( '1' !== $db_error ) : ?>
230+
<p><em><?php echo esc_html( $db_error ); ?></em></p>
231+
<?php endif; ?>
232+
</div>
233+
<?php
234+
}
235+
);
236+
}
237+
215238
if ( ! isset( $_GET['mskd_upgrade_db'] ) ) {
216239
return;
217240
}
@@ -225,11 +248,17 @@ function () {
225248
wp_die( esc_html__( 'Security check failed.', 'mail-system-by-katsarov-design' ) );
226249
}
227250

228-
// Force re-run the upgrade by temporarily setting version to 1.0.0.
229-
update_option( 'mskd_db_version', '1.0.0' );
251+
// Run full activation: uses dbDelta to create missing tables and columns.
252+
\MSKD_Activator::activate();
230253

231-
// Run upgrade.
232-
\MSKD_Activator::maybe_upgrade();
254+
// Verify the schema is now valid.
255+
if ( ! $this->is_database_schema_valid() ) {
256+
global $wpdb;
257+
$db_error = $wpdb->last_error;
258+
$error_param = $db_error ? '&mskd_db_error=' . rawurlencode( $db_error ) : '&mskd_db_error=1';
259+
wp_safe_redirect( admin_url( 'admin.php?page=' . self::PAGE_PREFIX . 'dashboard' . $error_param ) );
260+
exit;
261+
}
233262

234263
// Redirect to remove the query args.
235264
wp_safe_redirect( admin_url( 'admin.php?page=' . self::PAGE_PREFIX . 'dashboard&mskd_db_updated=1' ) );
@@ -253,7 +282,7 @@ private function render_database_repair_notice(): void {
253282
<strong><?php esc_html_e( 'Mail System Database Repair Required', 'mail-system-by-katsarov-design' ); ?></strong>
254283
</p>
255284
<p>
256-
<?php esc_html_e( 'Some required database columns are missing. This may cause subscription confirmation links to fail. Click the button below to repair the database.', 'mail-system-by-katsarov-design' ); ?>
285+
<?php esc_html_e( 'Some required database tables or columns are missing. This may cause subscription confirmation links to fail. Click the button below to repair the database.', 'mail-system-by-katsarov-design' ); ?>
257286
</p>
258287
<p>
259288
<a href="<?php echo esc_url( $upgrade_url ); ?>" class="button button-primary">
@@ -272,11 +301,23 @@ private function render_database_repair_notice(): void {
272301
private function is_database_schema_valid(): bool {
273302
global $wpdb;
274303

275-
// Check if opt_in_token column exists in subscribers table.
304+
$table = $wpdb->prefix . 'mskd_subscribers';
305+
306+
// First check the table itself exists.
307+
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Schema check.
308+
$table_exists = $wpdb->get_var(
309+
$wpdb->prepare( 'SHOW TABLES LIKE %s', $table )
310+
);
311+
312+
if ( ! $table_exists ) {
313+
return false;
314+
}
315+
316+
// Then check the opt_in_token column exists.
276317
// phpcs:ignore WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching -- Schema check.
277318
$column_exists = $wpdb->get_results(
278319
$wpdb->prepare(
279-
"SHOW COLUMNS FROM {$wpdb->prefix}mskd_subscribers LIKE %s",
320+
"SHOW COLUMNS FROM {$table} LIKE %s",
280321
'opt_in_token'
281322
)
282323
);

0 commit comments

Comments
 (0)