|
| 1 | +<?php // phpcs:ignore WordPress.Files.FileName.NotHyphenatedLowercase, WordPress.Files.FileName.InvalidClassFileName |
| 2 | +/** |
| 3 | + * Migration 1.4.2.2 - align Ideas roadmap status enum with the documented 4-lane spec. |
| 4 | + * |
| 5 | + * The 1.4.2 readme advertised four roadmap status lanes (planned, in progress, |
| 6 | + * shipped, declined) but the schema and admin UI shipped six lanes from the |
| 7 | + * earlier 1.4.2.1 backfill (submitted, under_review, planned, in_progress, |
| 8 | + * completed, declined). This migration brings the data and the column type |
| 9 | + * into alignment with the readme. |
| 10 | + * |
| 11 | + * Data remap end-state: |
| 12 | + * |
| 13 | + * - 'submitted' -> NULL (newly posted ideas live in the space's |
| 14 | + * normal feed; they enter the roadmap only |
| 15 | + * when an owner explicitly assigns a status) |
| 16 | + * - 'under_review' -> NULL (pre-decision state, same semantics as NULL) |
| 17 | + * - 'completed' -> 'shipped' (rename only - same meaning, customer-facing |
| 18 | + * word "shipped" matches the readme) |
| 19 | + * |
| 20 | + * Sequence is non-obvious: the new value 'shipped' is not in the old ENUM, |
| 21 | + * so we cannot UPDATE rows to 'shipped' before extending the ENUM. Order: |
| 22 | + * |
| 23 | + * 1. NULL out 'submitted' and 'under_review' rows (still valid values). |
| 24 | + * 2. ALTER ENUM to a transitional set that contains BOTH old and new |
| 25 | + * ('completed' AND 'shipped' simultaneously) so step 3 can succeed. |
| 26 | + * 3. UPDATE 'completed' rows to 'shipped'. |
| 27 | + * 4. ALTER ENUM to the final 4-value spec. |
| 28 | + * |
| 29 | + * Doing the rename through a single ALTER (drop 'completed' + add 'shipped') |
| 30 | + * would cause MySQL to coerce existing 'completed' rows to '' (empty string) |
| 31 | + * before the UPDATE could rename them. |
| 32 | + * |
| 33 | + * @package Jetonomy |
| 34 | + */ |
| 35 | + |
| 36 | +namespace Jetonomy\DB\Migrations; |
| 37 | + |
| 38 | +defined( 'ABSPATH' ) || exit; |
| 39 | + |
| 40 | +class Migration_1_4_2_2 { |
| 41 | + |
| 42 | + public function up(): void { |
| 43 | + global $wpdb; |
| 44 | + $posts_table = $wpdb->prefix . 'jt_posts'; |
| 45 | + |
| 46 | + // phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 47 | + |
| 48 | + // Step 1: drop the two pre-decision states. NULL is still permitted |
| 49 | + // by the column DEFAULT, so this is a no-coercion update. |
| 50 | + $wpdb->query( |
| 51 | + "UPDATE {$posts_table} SET idea_status = NULL WHERE idea_status IN ('submitted','under_review')" |
| 52 | + ); |
| 53 | + |
| 54 | + // Step 2: transitional ENUM that includes both 'completed' and the |
| 55 | + // new 'shipped' value, so step 3's UPDATE has a valid target. |
| 56 | + $wpdb->query( |
| 57 | + "ALTER TABLE {$posts_table} |
| 58 | + MODIFY COLUMN idea_status ENUM('submitted','under_review','planned','in_progress','completed','shipped','declined') DEFAULT NULL" |
| 59 | + ); |
| 60 | + |
| 61 | + // Step 3: rename 'completed' rows to 'shipped'. |
| 62 | + $wpdb->query( |
| 63 | + "UPDATE {$posts_table} SET idea_status = 'shipped' WHERE idea_status = 'completed'" |
| 64 | + ); |
| 65 | + |
| 66 | + // Step 3b: rescue rows that were coerced to '' on a previous (broken) |
| 67 | + // run of this migration that ALTERed before UPDATEing. Safe no-op on |
| 68 | + // fresh installs because '' is not used anywhere as a real value. |
| 69 | + $wpdb->query( |
| 70 | + "UPDATE {$posts_table} SET idea_status = NULL WHERE idea_status = ''" |
| 71 | + ); |
| 72 | + |
| 73 | + // Step 4: final ENUM in the documented 4-value form. |
| 74 | + $wpdb->query( |
| 75 | + "ALTER TABLE {$posts_table} |
| 76 | + MODIFY COLUMN idea_status ENUM('planned','in_progress','shipped','declined') DEFAULT NULL" |
| 77 | + ); |
| 78 | + |
| 79 | + // phpcs:enable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.NoCaching, WordPress.DB.PreparedSQL.InterpolatedNotPrepared |
| 80 | + } |
| 81 | +} |
0 commit comments