| @@ -336,11 +336,88 @@ | ||
| 336 | 336 | // Update upgrade version option only for who had previous version to trigger initial upgrade tracking |
| 337 | 337 | update_option( $this->token . '_db_upgrade_version', '0.0.0', false ); |
| 338 | 338 | } |
| 339 | 339 | |
| 340 | + /** | |
| 341 | + * If DB version below 1.0.6 | |
| 342 | + * | |
| 343 | + * @since 1.3.12 | |
| 344 | + * Flatten recursively nested wpmcs_status_data caused by legacy set_status writes. | |
| 345 | + */ | |
| 346 | + if ( version_compare( $current_version, '1.0.6', '<' ) ) { | |
| 347 | + $this->repair_nested_status_data(); | |
| 348 | + } | |
| 340 | 349 | |
| 341 | 350 | |
| 351 | + | |
| 342 | 352 | update_option( $this->token.'_db_version', $latest_version, true ); |
| 353 | + } | |
| 354 | + | |
| 355 | + /** | |
| 356 | + * One-time repair for recursively nested wpmcs_status_data. | |
| 357 | + * Flattens status entries caused by legacy set_status writes that used get_option directly. | |
| 358 | + * | |
| 359 | + * @since 1.3.12 | |
| 360 | + * @return void | |
| 361 | + */ | |
| 362 | + private function repair_nested_status_data() { | |
| 363 | + $meta_name = Schema::getConstant('STATUS_KEY'); | |
| 364 | + $current_settings = Utils::get_option('status', [], $meta_name); | |
| 365 | + | |
| 366 | + if (!is_array($current_settings) || empty($current_settings)) { | |
| 367 | + return; | |
| 368 | + } | |
| 369 | + | |
| 370 | + $known_keys = ['cdnRead', 'storageCredentials']; | |
| 371 | + $collected = []; | |
| 372 | + $this->collect_status_entries($current_settings, $collected); | |
| 373 | + | |
| 374 | + if (empty($collected)) { | |
| 375 | + return; | |
| 376 | + } | |
| 377 | + | |
| 378 | + $normalized = []; | |
| 379 | + foreach ($known_keys as $key) { | |
| 380 | + if (isset($collected[$key])) { | |
| 381 | + $normalized[$key] = $collected[$key]; | |
| 382 | + } | |
| 383 | + } | |
| 384 | + | |
| 385 | + if (empty($normalized) || $normalized === $current_settings) { | |
| 386 | + return; | |
| 387 | + } | |
| 388 | + | |
| 389 | + Utils::update_option('status', $normalized, $meta_name); | |
| 390 | + } | |
| 391 | + | |
| 392 | + /** | |
| 393 | + * Collect status entries from all nesting levels, preferring the latest check. | |
| 394 | + * @since 1.3.12 | |
| 395 | + * @param array $settings | |
| 396 | + * @param array $collected | |
| 397 | + * @return void | |
| 398 | + */ | |
| 399 | + private function collect_status_entries($settings, &$collected) { | |
| 400 | + if (!is_array($settings)) { | |
| 401 | + return; | |
| 402 | + } | |
| 403 | + | |
| 404 | + $known_keys = ['cdnRead', 'storageCredentials']; | |
| 405 | + | |
| 406 | + foreach ($known_keys as $key) { | |
| 407 | + if (isset($settings[$key]) && is_array($settings[$key]) && array_key_exists('status', $settings[$key])) { | |
| 408 | + $entry = $settings[$key]; | |
| 409 | + $checked = isset($entry['lastChecked']) ? (int) $entry['lastChecked'] : 0; | |
| 410 | + | |
| 411 | + if (!isset($collected[$key]) || $checked >= ($collected[$key]['lastChecked'] ?? 0)) { | |
| 412 | + $collected[$key] = $entry; | |
| 413 | + } | |
| 414 | + } | |
| 415 | + } | |
| 416 | + | |
| 417 | + if (isset($settings['status']) && is_array($settings['status'])) { | |
| 418 | + $this->collect_status_entries($settings['status'], $collected); | |
| 419 | + } | |
| 343 | 420 | } |
| 344 | 421 | |
| 345 | 422 | /** |
| 346 | 423 | * Ensures only one instance of Class is loaded or can be loaded. |