Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save xlplugins/4a013a94f232ea739f9cd18b30b16015 to your computer and use it in GitHub Desktop.

Select an option

Save xlplugins/4a013a94f232ea739f9cd18b30b16015 to your computer and use it in GitHub Desktop.
FunnelKit - conversion tracking journey column fix
<?php
/**
* Plugin Name: FunnelKit - conversion tracking journey column fix
* Description: On-demand repair for the repeating "Duplicate column name 'journey'" database error. Runs only when an administrator loads a wp-admin URL with ?fk_fix_journey=1 - it verifies the column and marks that migration done, so the plugin stops re-running the ALTER and printing the error into admin responses (which blocks plugin uploads). Idle otherwise.
* Version: 1.1.0
*/
defined( 'ABSPATH' ) || exit;
add_action( 'admin_init', function () {
/**
* Manual trigger only: load any wp-admin page with ?fk_fix_journey=1 while logged in as an
* administrator, e.g. /wp-admin/index.php?fk_fix_journey=1. On every other request this file
* costs one isset() and does nothing.
*/
if ( ! isset( $_GET['fk_fix_journey'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.Recommended
return;
}
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
global $wpdb;
$table = $wpdb->prefix . 'bwf_conversion_tracking';
$report = array();
/**
* Errors are silenced only for the checks below, then restored. wpdb reports a failed query by
* echoing it into the response, and a database error printed mid-page is the very thing that
* breaks the plugin uploader - a repair routine must not be able to add to it. The outcome is
* decided by re-reading the schema, not by the error text, and reported at the end instead.
*/
$suppress = $wpdb->suppress_errors( true );
/**
* SHOW COLUMNS asks the schema this connection is actually on, so it always agrees with the
* ALTER. The INFORMATION_SCHEMA lookup the plugin uses is filtered by DB_NAME, which on this
* host reports the column as missing even though it exists - that mismatch is what makes the
* migration ALTER a column that is already there, fail, and repeat on every admin request.
*/
$has_journey = static function () use ( $wpdb, $table ) {
return (bool) $wpdb->get_var( $wpdb->prepare( "SHOW COLUMNS FROM `{$table}` LIKE %s", 'journey' ) );
};
$report[] = 'Table: ' . $table;
$report[] = 'Flag before: ' . get_option( 'wffn_conversion_tracking_db_updater', '(not set)' );
if ( ! $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $wpdb->esc_like( $table ) ) ) ) {
$report[] = 'Result: table does not exist - nothing to repair. It is created with the journey column already in place.';
} else {
if ( $has_journey() ) {
$report[] = 'Column `journey`: already present.';
} else {
$report[] = 'Column `journey`: missing - adding it.';
$wpdb->query( "ALTER TABLE `{$table}` ADD `journey` longtext AFTER `referrer`" );
if ( ! empty( $wpdb->last_error ) ) {
$report[] = 'ALTER reported: ' . $wpdb->last_error;
}
}
/** Column present, however it got there - the migration has nothing left to do. */
if ( $has_journey() ) {
update_option( 'wffn_conversion_tracking_db_updater', '1.1', true );
$report[] = 'Flag after: ' . get_option( 'wffn_conversion_tracking_db_updater' ) . ' - the migration will not run again.';
$report[] = 'Result: fixed. Remove this file once the admin loads without the database error.';
} else {
$report[] = 'Result: the column could not be added, so the flag was left alone and the migration will retry. Send this output back to support.';
}
}
$wpdb->suppress_errors( $suppress );
wp_die(
'<h2>FunnelKit journey column fix</h2><pre style="white-space:pre-wrap">' . esc_html( implode( "\n", $report ) ) . '</pre>',
'FunnelKit journey column fix',
array( 'response' => 200 )
);
}, 1 );
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment