= $target ) { return; } require_once ABSPATH . 'wp-admin/includes/upgrade.php'; for ( $i = $current; $i < $target; $i++ ) { if ( ! isset( self::MIGRATIONS[ $i ] ) ) { break; } $class = self::MIGRATIONS[ $i ]; if ( ! class_exists( $class ) ) { // Migration file not autoloaded — load explicitly. $file = $this->class_to_file( $class ); if ( file_exists( $file ) ) { require_once $file; } } if ( class_exists( $class ) ) { $migration = new $class(); $migration->up(); } update_option( self::VERSION_OPTION, $i + 1 ); } } /** * Get current schema version. * * @return int */ public function get_current_version(): int { return (int) get_option( self::VERSION_OPTION, 0 ); } /** * Convert migration class name to file path. * * PR_Core_Migration_0001_Dosing_Rows => migrations/class-pr-core-migration-0001-dosing-rows.php * * @param string $class_name Fully-qualified class name. * @return string Absolute file path. */ private function class_to_file( string $class_name ): string { $suffix = substr( $class_name, 8 ); // Strip 'PR_Core_'. $filename = 'class-pr-core-' . str_replace( '_', '-', strtolower( $suffix ) ) . '.php'; return PR_CORE_PLUGIN_DIR . 'includes/migrations/' . $filename; } }