| @@ -137,12 +137,54 @@ | ||
| 137 | 137 | wdesignkit_invalidate_widget_registry( $builder_slug ); |
| 138 | 138 | } |
| 139 | 139 | } |
| 140 | 140 | |
| 141 | + // Collect the registry caches belonging to OTHER versions while we are here. The line | |
| 142 | + // above only clears the current version's keys — by design, since those are the ones that | |
| 143 | + // might be stale. The old versions' keys were never deleted by anything, so each release | |
| 144 | + // left one permanent row per builder in wp_options (verified: twelve rows across three | |
| 145 | + // versions on a twice-upgraded site). Activation is the natural place for the sweep: it is | |
| 146 | + // the one moment the plugin knows the version may just have changed. | |
| 147 | + if ( function_exists( 'wdesignkit_purge_stale_widget_registries' ) ) { | |
| 148 | + wdesignkit_purge_stale_widget_registries(); | |
| 149 | + } | |
| 150 | + | |
| 141 | 151 | // Scheduling belongs here rather than in the request path (ClickUp 86d41cp05). |
| 142 | 152 | if ( function_exists( 'wdesignkit_schedule_widget_trash_purge' ) ) { |
| 143 | 153 | wdesignkit_schedule_widget_trash_purge(); |
| 144 | 154 | } |
| 155 | + | |
| 156 | + /* | |
| 157 | + * Report this activation to the analytics hub, and stamp the install time. | |
| 158 | + * | |
| 159 | + * The SDK's `activated_plugin` listener cannot see a plugin's OWN activation: WordPress has | |
| 160 | + * already fired `plugins_loaded` before it includes the plugin file, so the plugins_loaded | |
| 161 | + * callback in wdesignkit.php never runs this request, Posimyth_Tracker_WDK::init() never | |
| 162 | + * registers, and nothing is listening when `activated_plugin` fires. Deactivation worked | |
| 163 | + * (the plugin IS loaded there) while activation silently reported nothing — and because | |
| 164 | + * on_deactivate() clears the activate-reported flag, every deactivate/reactivate cycle lost | |
| 165 | + * one activation from the hub's count for good. on_self_activate() is the SDK's documented | |
| 166 | + * entry point for exactly this, and it is consent-gated like every other event. | |
| 167 | + * | |
| 168 | + * The subclass has to be required by hand here for the same reason: the plugins_loaded | |
| 169 | + * callback that normally requires it does not run during this request. The shared base is | |
| 170 | + * already loaded — posimyth_sdk_register() in wdesignkit.php loads immediately when | |
| 171 | + * plugins_loaded has already fired. | |
| 172 | + * | |
| 173 | + * The leading backslash is required and is not decoration: this file declares | |
| 174 | + * `namespace wdkit` and the SDK class is global, so without it PHP resolves the call as | |
| 175 | + * `wdkit\Posimyth_Tracker_WDK` and fatals — exactly as documented in wdkit_deactivation() | |
| 176 | + * below. The class_exists() guard does not protect against that, because its argument is a | |
| 177 | + * string and strings are always read as fully qualified. | |
| 178 | + */ | |
| 179 | + $wdkit_tracker = WDKIT_PATH . 'includes/posimyth-sdk/class-posimyth-tracker-wdk.php'; | |
| 180 | + if ( is_readable( $wdkit_tracker ) ) { | |
| 181 | + require_once $wdkit_tracker; | |
| 182 | + } | |
| 183 | + | |
| 184 | + if ( class_exists( 'Posimyth_Tracker_WDK' ) ) { | |
| 185 | + \Posimyth_Tracker_WDK::on_self_activate(); | |
| 186 | + } | |
| 145 | 187 | } |
| 146 | 188 | |
| 147 | 189 | /** |
| 148 | 190 | * Plugin deactivation. |
| @@ -155,8 +197,29 @@ | ||
| 155 | 197 | if ( ! empty( $get_white_label ) ) { |
| 156 | 198 | delete_option( 'wkit_white_label' ); |
| 157 | 199 | } |
| 158 | 200 | |
| 201 | + /* | |
| 202 | + * Stop the analytics heartbeat. | |
| 203 | + * | |
| 204 | + * Posimyth_Tracker_WDK::init() schedules a weekly `posimyth_heartbeat_wdk` event. Without | |
| 205 | + * this, deactivating the plugin leaves that event in WordPress forever — firing against a | |
| 206 | + * hook with no listener and showing up in every cron listing. Deactivation only, never | |
| 207 | + * uninstall: purge_state() in uninstall.php handles the stored options, and calling that | |
| 208 | + * here would wipe consent every time someone toggled the plugin off. | |
| 209 | + * | |
| 210 | + * The leading backslash is required and is not decoration. This file declares | |
| 211 | + * `namespace wdkit`, and the SDK class is global — without it PHP resolves the call as | |
| 212 | + * `wdkit\Posimyth_Tracker_WDK` and fatals on deactivation. The class_exists() guard above | |
| 213 | + * does NOT catch that: its argument is a string, which is always read as fully qualified, | |
| 214 | + * so the guard passed and the very next line died. | |
| 215 | + */ | |
| 216 | + if ( class_exists( 'Posimyth_Tracker_WDK' ) ) { | |
| 217 | + \Posimyth_Tracker_WDK::unschedule(); | |
| 218 | + } | |
| 219 | + | |
| 220 | + // Widget-trash purge cron, added on release. Unrelated to the heartbeat above — both are | |
| 221 | + // scheduled by this plugin, so deactivation has to clear both or the survivor is orphaned. | |
| 159 | 222 | $timestamp = wp_next_scheduled( 'wdesignkit_purge_widget_trash_cron' ); |
| 160 | 223 | if ( $timestamp ) { |
| 161 | 224 | wp_unschedule_event( $timestamp, 'wdesignkit_purge_widget_trash_cron' ); |
| 162 | 225 | } |
| @@ -205,13 +268,22 @@ | ||
| 205 | 268 | require_once WDKIT_INCLUDES . 'admin/class-wdkit-enqueue.php'; |
| 206 | 269 | require_once WDKIT_INCLUDES . 'admin/class-wdesignkit-data-query.php'; |
| 207 | 270 | require_once WDKIT_INCLUDES . 'admin/class-wdkit-depends-installer.php'; |
| 208 | 271 | |
| 272 | + // PHP importer service layer. Class definitions only - registers no hooks and | |
| 273 | + // instantiates nothing, so this is inert until something calls it. The browser | |
| 274 | + // importer does not, and its AJAX path is unchanged. | |
| 275 | + require_once WDKIT_INCLUDES . 'admin/import/import-load.php'; | |
| 276 | + | |
| 209 | 277 | // Must load before widget-load-files.php: the Gutenberg/Gutenberg Core loaders |
| 210 | 278 | // register their widgets synchronously in their own constructor (not on a later |
| 211 | 279 | // hook), so wdesignkit_get_widget_registry() has to already be defined by the |
| 212 | 280 | // time widget-load-files.php requires and instantiates them below. |
| 213 | 281 | require_once WDKIT_INCLUDES . 'abilities/class-wdk-ability-main.php'; |
| 282 | + | |
| 283 | + // WordPress 7.1 ability execution lifecycle hooks. Inert on older versions | |
| 284 | + // (the hook names simply do not exist), so it is loaded unconditionally. | |
| 285 | + require_once WDKIT_INCLUDES . 'abilities/class-wdk-ability-lifecycle.php'; | |
| 214 | 286 | |
| 215 | 287 | require_once WDKIT_INCLUDES . 'widget-load/widget-load-files.php'; |
| 216 | 288 | require_once WDKIT_INCLUDES . 'widget-load/dynamic-listing/dynamic-listing.php'; |
| 217 | 289 | } |