| @@ -78,4 +78,73 @@ | ||
| 78 | 78 | */ |
| 79 | 79 | function wpf_update_350_db_version() { |
| 80 | 80 | update_option('wpfunnels_db_version', '3.2.0'); |
| 81 | 81 | } |
| 82 | + | |
| 83 | + | |
| 84 | +/** | |
| 85 | + * Create checkout visits table for native checkout conversion rate tracking. | |
| 86 | + * | |
| 87 | + * @since 3.11.0 | |
| 88 | + */ | |
| 89 | +function wpf_create_3110_checkout_visits_table() { | |
| 90 | + global $wpdb; | |
| 91 | + $wpdb->hide_errors(); | |
| 92 | + $charset_collate = $wpdb->get_charset_collate(); | |
| 93 | + $table_name = $wpdb->prefix . 'wpfnl_checkout_visits'; | |
| 94 | + | |
| 95 | + $sql = "CREATE TABLE IF NOT EXISTS $table_name ( | |
| 96 | + id bigint(20) unsigned NOT NULL AUTO_INCREMENT, | |
| 97 | + type varchar(10) NOT NULL DEFAULT 'store', | |
| 98 | + funnel_id bigint(20) unsigned NOT NULL DEFAULT 0, | |
| 99 | + session_hash varchar(32) NOT NULL, | |
| 100 | + visit_date date NOT NULL, | |
| 101 | + date_created datetime NOT NULL, | |
| 102 | + PRIMARY KEY (id), | |
| 103 | + UNIQUE KEY unique_visit (session_hash, type, funnel_id, visit_date) | |
| 104 | + ) $charset_collate;"; | |
| 105 | + | |
| 106 | + require_once ABSPATH . 'wp-admin/includes/upgrade.php'; | |
| 107 | + dbDelta( $sql ); | |
| 108 | +} | |
| 109 | + | |
| 110 | + | |
| 111 | +/** | |
| 112 | + * Add an index on (funnel_id, status) to the stats table to avoid full | |
| 113 | + * table scans in funnel-level analytics lookups (e.g. the funnel canvas). | |
| 114 | + * | |
| 115 | + * Guarded with SHOW INDEX so it stays idempotent on sites where the index | |
| 116 | + * may already have been applied manually. | |
| 117 | + * | |
| 118 | + * Return value follows the batched-migration contract documented on | |
| 119 | + * Wpfnl_Activator::run_update_callback_end(): true means "there is more work | |
| 120 | + * left, queue me again", false means "finished". This callback completes in a | |
| 121 | + * single pass, so it always returns false. Returning true here is what caused | |
| 122 | + * the runaway ActionScheduler loop fixed in 3.12.13 — do not change it back. | |
| 123 | + * | |
| 124 | + * @return bool Always false; this migration never needs a second pass. | |
| 125 | + * | |
| 126 | + * @since 3.12.12 | |
| 127 | + */ | |
| 128 | +function wpf_add_31212_stats_funnel_status_index() { | |
| 129 | + global $wpdb; | |
| 130 | + $table = $wpdb->prefix . 'wpfnl_stats'; | |
| 131 | + | |
| 132 | + // SHOW INDEX errors outright on a missing table, so confirm it exists | |
| 133 | + // first. Sites that predate the stats table get it from the 3.5.0 | |
| 134 | + // callback, which ActionScheduler runs ahead of this one. | |
| 135 | + $table_exists = $wpdb->get_var( $wpdb->prepare( 'SHOW TABLES LIKE %s', $table ) ); // phpcs:ignore | |
| 136 | + if ( ! $table_exists ) { | |
| 137 | + return false; | |
| 138 | + } | |
| 139 | + | |
| 140 | + $exists = $wpdb->get_var( $wpdb->prepare( | |
| 141 | + 'SHOW INDEX FROM ' . $table . ' WHERE Key_name = %s', | |
| 142 | + 'idx_funnel_status' | |
| 143 | + ) ); // phpcs:ignore | |
| 144 | + | |
| 145 | + if ( ! $exists ) { | |
| 146 | + $wpdb->query( "ALTER TABLE {$table} ADD INDEX idx_funnel_status (funnel_id, status)" ); // phpcs:ignore | |
| 147 | + } | |
| 148 | + | |
| 149 | + return false; | |
| 150 | +} | |