Managing data migration and version upgrades is critical for maintaining system stability and user experience. This guide covers comprehensive strategies for migrating ShahiAssist data and handling upgrades.
Version Upgrade Strategy
Semantic Versioning
ShahiAssist follows semantic versioning (MAJOR.MINOR.PATCH):
- MAJOR: Breaking changes requiring migration
- MINOR: New features, backward compatible
- PATCH: Bug fixes, backward compatible
- WordPress Database Migrations
- Semantic Versioning
- Database Change Management
- WordPress Upgrade API
Upgrade Path Planning
`php
class ShahiAssistUpgradeManager {
private $current_version;
private $target_version;
public function __construct() {
$this->currentversion = getoption(‘shahiassistversion’, ‘1.0.0’);
}
public function upgradeto($targetversion) {
$this->targetversion = $targetversion;
// Get upgrade path
$upgradesteps = $this->getupgradepath($this->currentversion, $target_version);
// Execute upgrades in order
foreach ($upgrade_steps as $step) {
$this->executeupgradestep($step);
}
// Update version
updateoption(‘shahiassistversion’, $targetversion);
}
private function getupgradepath($from, $to) {
// Define upgrade steps between versions
$upgrade_paths = [
‘1.0.0’ => [‘1.1.0’, ‘1.2.0’, ‘2.0.0’],
‘1.1.0’ => [‘1.2.0’, ‘2.0.0’],
‘1.2.0’ => [‘2.0.0’],
‘2.0.0’ => [‘2.1.0’, ‘3.0.0’],
];
$path = [];
$current = $from;
while (version_compare($current, $to, ‘<')) {
if (!isset($upgrade_paths[$current])) {
break;
}
$nextversions = $upgradepaths[$current];
$next = null;
foreach ($next_versions as $version) {
if (version_compare($version, $to, ‘<=')) {
$next = $version;
break;
}
}
if (!$next) {
break;
}
$path[] = $next;
$current = $next;
}
return $path;
}
private function executeupgradestep($version) {
$method = ‘upgradeto‘ . strreplace(‘.’, ‘‘, $version);
if (method_exists($this, $method)) {
$this->$method();
}
}
}
`
Database Migrations
Migration Framework
`php
abstract class ShahiAssist_Migration {
protected $db_version = ‘1.0’;
abstract public function up();
abstract public function down();
public function get_version() {
return $this->db_version;
}
}
class CreateTicketsTableMigration extends ShahiAssistMigration {
protected $db_version = ‘1.1’;
public function up() {
global $wpdb;
$tablename = $wpdb->prefix . ‘shahiassist_tickets’;
$sql = “CREATE TABLE $table_name (
id int(11) NOT NULL AUTO_INCREMENT,
title varchar(255) NOT NULL,
description text,
status varchar(50) DEFAULT ‘open’,
priority varchar(20) DEFAULT ‘medium’,
createdat datetime DEFAULT CURRENTTIMESTAMP,
updatedat datetime DEFAULT CURRENTTIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (id),
INDEX idx_status (status),
INDEX idx_priority (priority)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4unicodeci;”;
require_once(ABSPATH . ‘wp-admin/includes/upgrade.php’);
dbDelta($sql);
}
public function down() {
global $wpdb;
$tablename = $wpdb->prefix . ‘shahiassist_tickets’;
$wpdb->query(“DROP TABLE IF EXISTS $table_name”);
}
}
`
Migration Runner
`php
class ShahiAssistMigrationRunner {
private $migrations_path;
private $completed_migrations = [];
public function __construct() {
$this->migrationspath = plugindir_path(FILE) . ‘migrations/’;
$this->completedmigrations = getoption(‘shahiassistcompleted_migrations’, []);
}
public function run_migrations() {
$migrationfiles = glob($this->migrationspath . ‘*.php’);
foreach ($migration_files as $file) {
$migration_class = basename($file, ‘.php’);
if (inarray($migrationclass, $this->completed_migrations)) {
continue;
}
require_once $file;
$migration = new $migration_class();
try {
$migration->up();
$this->completedmigrations[] = $migrationclass;
updateoption(‘shahiassistcompletedmigrations’, $this->completed_migrations);
errorlog(“Migration completed: $migrationclass”);
} catch (Exception $e) {
errorlog(“Migration failed: $migrationclass – ” . $e->getMessage());
// Rollback if needed
$migration->down();
break;
}
}
}
public function rollbackmigration($migrationclass) {
if (!inarray($migrationclass, $this->completed_migrations)) {
return false;
}
$file = $this->migrationspath . $migrationclass . ‘.php’;
if (!file_exists($file)) {
return false;
}
require_once $file;
$migration = new $migration_class();
$migration->down();
$key = arraysearch($migrationclass, $this->completed_migrations);
unset($this->completed_migrations[$key]);
updateoption(‘shahiassistcompletedmigrations’, $this->completed_migrations);
return true;
}
}
`
Data Migration Scripts
Post Type Migration
`php
// Migrate from custom table to WordPress posts
function migrateticketsto_posts() {
global $wpdb;
$oldtable = $wpdb->prefix . ‘shahiassist_tickets’;
$tickets = $wpdb->getresults(“SELECT * FROM $oldtable”);
foreach ($tickets as $ticket) {
$post_data = [
‘post_title’ => $ticket->title,
‘post_content’ => $ticket->description,
‘post_type’ => ‘ticket’,
‘post_status’ => ‘publish’,
‘postdate’ => $ticket->createdat,
‘postmodified’ => $ticket->updatedat,
];
$postid = wpinsertpost($postdata);
if ($post_id) {
// Migrate meta data
updatepostmeta($postid, ‘ticket_status’, $ticket->status);
updatepostmeta($postid, ‘ticket_priority’, $ticket->priority);
updatepostmeta($postid, ‘migrated_from’, $ticket->id);
}
}
// Mark migration as complete
updateoption(‘shahiassistticketmigration_complete’, true);
}
`
Settings Migration
`php
// Migrate old settings structure to new
function migratesettingsstructure() {
$oldsettings = getoption(‘shahiassistold_settings’, []);
$new_settings = [];
// Transform old settings to new structure
if (isset($oldsettings[’emailnotifications’])) {
$new_settings[‘notifications’] = [
’email’ => $oldsettings[’emailnotifications’],
‘enabled’ => true,
];
}
if (isset($oldsettings[‘ticketcategories’])) {
$newsettings[‘categories’] = arraymap(function($cat) {
return [
‘name’ => $cat[‘name’],
‘slug’ => sanitize_title($cat[‘name’]),
‘description’ => $cat[‘description’] ?? ”,
];
}, $oldsettings[‘ticketcategories’]);
}
updateoption(‘shahiassistsettings’, $newsettings);
deleteoption(‘shahiassistoldsettings’);
}
`
User Data Migration
`php
// Migrate user roles and capabilities
function migrateuserroles() {
$users = getusers([‘rolenotin’ => [‘administrator’]]);
foreach ($users as $user) {
$oldrole = getusermeta($user->ID, ‘shahiassistoldrole’, true);
if ($oldrole === ‘supportagent’) {
$user->addrole(‘shahiagent’);
} elseif ($old_role === ‘customer’) {
$user->add_role(‘customer’);
}
// Migrate user preferences
$oldprefs = getusermeta($user->ID, ‘shahiassist_preferences’, true);
if ($old_prefs) {
updateusermeta($user->ID, ‘shahiassistnewpreferences’, $oldprefs);
deleteusermeta($user->ID, ‘shahiassistpreferences’);
}
}
}
`
Breaking Changes Handling
API Changes
`php
// Handle deprecated API endpoints
addaction(‘restapi_init’, function() {
// Register new endpoint
registerrestroute(‘shahi-assist/v2’, ‘/tickets’, [
‘methods’ => ‘GET’,
‘callback’ => ‘getticketsv2′,
‘permissioncallback’ => ‘checkapi_permissions’,
]);
// Handle deprecated v1 endpoint with warning
registerrestroute(‘shahi-assist/v1’, ‘/tickets’, [
‘methods’ => ‘GET’,
‘callback’ => function() {
// Log deprecation warning
error_log(‘Deprecated API endpoint used: /shahi-assist/v1/tickets’);
// Forward to new endpoint
return getticketsv2();
},
‘permissioncallback’ => ‘checkapi_permissions’,
]);
});
`
Hook Changes
`php
// Maintain backward compatibility for hooks
addaction(‘shahiassistticketcreated’, function($ticket_id) {
// New hook implementation
doaction(‘shahiassistnewticketcreated’, $ticketid);
// Trigger deprecated hook for backward compatibility
doaction(‘shahiassistoldticketcreated’, $ticketid);
}, 10, 1);
// Deprecation notice for old hooks
addaction(‘deprecatedhookused’, function($hookname, $replacement, $version) {
if (strpos($hookname, ‘shahiassistold‘) === 0) {
errorlog(“Deprecated hook ‘$hookname’ used. Use ‘$replacement’ instead. Deprecated since version $version.”);
}
});
`
Rollback Strategies
Safe Rollback
`php
class ShahiAssistRollbackManager {
private $backup_tables = [];
public function create_backup() {
global $wpdb;
$tablestobackup = [
$wpdb->posts,
$wpdb->postmeta,
$wpdb->prefix . ‘shahiassistcustom_table’
];
foreach ($tablestobackup as $table) {
$backuptable = $table . ‘backup‘ . date(‘YmdHis’);
$wpdb->query(“CREATE TABLE $backup_table AS SELECT * FROM $table”);
$this->backuptables[$table] = $backuptable;
}
updateoption(‘shahiassistbackuptables’, $this->backup_tables);
}
public function rollback() {
global $wpdb;
$backuptables = getoption(‘shahiassistbackup_tables’, []);
foreach ($backup_tables as $original => $backup) {
// Drop original table
$wpdb->query(“DROP TABLE IF EXISTS $original”);
// Restore from backup
$wpdb->query(“CREATE TABLE $original AS SELECT * FROM $backup”);
}
// Clean up backup tables
foreach ($backup_tables as $backup) {
$wpdb->query(“DROP TABLE IF EXISTS $backup”);
}
deleteoption(‘shahiassistbackuptables’);
}
}
`
Partial Rollback
`php
// Rollback specific changes
function rollbackspecificchanges($version) {
switch ($version) {
case ‘2.1.0’:
// Revert database schema changes
global $wpdb;
$wpdb->query(“ALTER TABLE {$wpdb->prefix}shahiassisttickets DROP COLUMN new_column”);
break;
case ‘2.0.0’:
// Revert post type changes
unregisterposttype(‘newposttype’);
break;
case ‘1.5.0’:
// Revert option changes
deleteoption(‘shahiassistnewoption’);
break;
}
}
`
Testing Migrations
Migration Testing Framework
`php
class ShahiAssistMigrationTest {
public function testmigration($migrationclass) {
// Create test database
$this->createtestdatabase();
// Run migration
$migration = new $migration_class();
$migration->up();
// Verify migration results
$this->verifymigrationresults($migration_class);
// Test rollback
$migration->down();
$this->verifyrollbackresults($migration_class);
// Clean up
$this->cleanuptestdatabase();
}
private function createtestdatabase() {
// Create isolated test environment
// Use WordPress testing framework or custom setup
}
private function verifymigrationresults($migration_class) {
// Check if tables exist, data is migrated correctly, etc.
global $wpdb;
switch ($migration_class) {
case ‘CreateTicketsTable_Migration’:
$tableexists = $wpdb->getvar(“SHOW TABLES LIKE ‘{$wpdb->prefix}shahiassisttickets'”);
assert($table_exists, ‘Tickets table should exist after migration’);
break;
}
}
}
`
Upgrade UI and User Communication
Admin Upgrade Interface
`php
// Add upgrade notice in admin
addaction(‘adminnotices’, function() {
$currentversion = getoption(‘shahiassistversion’);
$latest_version = ‘2.1.0’; // From update API
if (versioncompare($currentversion, $latest_version, ‘<')) { ?>
ShahiAssist Update Available Upgrade completed successfully!
A new version () is available.
‘;
}
// Display upgrade form
?>
Upgrade ShahiAssist
`
User Communication
`php
// Notify users about changes
function notifyusersof_changes($version) {
$users = getusers([‘rolein’ => [‘administrator’, ‘shahiagent’]]);
$changelog = getchangelogfor_version($version);
foreach ($users as $user) {
wp_mail(
$user->user_email,
“ShahiAssist Updated to $version”,
“ShahiAssist has been updated to version $version.\n\n” .
“Key changes:\n$changelog\n\n” .
“Please review the documentation for any required actions.”
);
}
}
function getchangelogfor_version($version) {
$changelogs = [
‘2.0.0’ => “- New ticket system architecture\n- Improved performance\n- Breaking changes in API endpoints”,
‘2.1.0’ => “- Added new features\n- Bug fixes\n- Performance improvements”,
];
return $changelogs[$version] ?? ‘Various improvements and bug fixes’;
}
`
Resources
Share this article
Still need help?
Our support team is ready to assist you with personalized guidance for your workspace.