$introduction_date, "callback" => $callback]; } \NeoLibrary\NeoGlobal\add_action_hook("neo_init:0", function () { \NeoLibrary\NeoGlobal\val("neo_global__migration_registration_closed", true); \NeoLibrary\NeoGlobal\synclock_dir(\NeoLibrary\NeoGlobal\cache_path(), function () { $stored_plugin_timestamp = \NeoLibrary\NeoGlobal\option__neo_global__last_migration_plugin_timestamp_neo_library(); $current_plugin_timestamp = \NeoLibrary\NeoGlobal\plugin_timestamp(); \NeoLibrary\NeoGlobal\option__neo_global__last_migration_plugin_timestamp_neo_library($current_plugin_timestamp); if (!($stored_plugin_timestamp > 0 && $current_plugin_timestamp > $stored_plugin_timestamp)) { return; } $old_plugin_date = \NeoLibrary\NeoGlobal\utc_date_string("Y-m-d", intval($stored_plugin_timestamp)); $migrations = \NeoLibrary\NeoGlobal\val("neo_global__migrations"); usort($migrations, function ($migration_a, $migration_b) { return strcmp($migration_a["date"], $migration_b["date"]); }); foreach ($migrations as $migration) { if (!($migration["date"] >= $old_plugin_date)) { continue; } try { $migration["callback"](); } catch (\Throwable $error) { \NeoLibrary\NeoGlobal\global_warn_with_module_name("_global-migration", "Migration failed for " . $migration["date"] . ": " . $error->getMessage() . " in " . $error->getTraceAsString()); } } }, scope: "migration-" . \NeoLibrary\NeoGlobal\plugin_slug() . "-" . \NeoLibrary\NeoGlobal\plugin_edition()); });