| @@ -257,12 +257,8 @@ | ||
| 257 | 257 | 'seo_analytics_google_analytics_property_id', |
| 258 | 258 | 'ga_analytics_account_id', |
| 259 | 259 | 'ga_analytics_data_stream_id', |
| 260 | 260 | |
| 261 | - // GA4 Tracking Code Injection (Pro) | |
| 262 | - 'ga4_auto_inject', | |
| 263 | - 'ga4_measurement_id', | |
| 264 | - | |
| 265 | 261 | // Search Console configuration |
| 266 | 262 | 'search_console_property', |
| 267 | 263 | |
| 268 | 264 | // AI features |
| @@ -649,22 +645,10 @@ | ||
| 649 | 645 | // Prime the option cache in one query before the loop. Every |
| 650 | 646 | // thinkrank_* option is autoload=off, so WordPress cannot serve them |
| 651 | 647 | // from `alloptions` and each Settings->get() below was its own |
| 652 | 648 | // round-trip — 16 of them on every anonymous front-end request, on |
| 653 | - // pages that use none of the values. Settings::get() memoizes within a | |
| 654 | - // request, so only the first read of each key ever hit the database; | |
| 655 | - // this collapses those first reads into a single query (#393). | |
| 656 | - // | |
| 657 | - // wp_prime_option_caches() is WP 6.4+; the plugin supports 6.0, so an | |
| 658 | - // older site simply keeps the previous behaviour. | |
| 659 | - if (function_exists('wp_prime_option_caches')) { | |
| 660 | - wp_prime_option_caches(array_map( | |
| 661 | - static function (string $key): string { | |
| 662 | - return 'thinkrank_' . $key; | |
| 663 | - }, | |
| 664 | - $category_config['keys'] | |
| 665 | - )); | |
| 666 | - } | |
| 649 | + // pages that use none of the values (#393). | |
| 650 | + $this->core_settings->prime($category_config['keys']); | |
| 667 | 651 | |
| 668 | 652 | $settings = []; |
| 669 | 653 | |
| 670 | 654 | foreach ($category_config['keys'] as $key) { |
| @@ -848,11 +832,15 @@ | ||
| 848 | 832 | } |
| 849 | 833 | break; |
| 850 | 834 | |
| 851 | 835 | case 'ai_provider': |
| 852 | - if (!in_array($value, ['openai', 'claude', 'gemini', 'openrouter'], true)) { | |
| 836 | + // '' is legal: it is Settings::AI_PROVIDER_NONE, the state a | |
| 837 | + // fresh install starts in and the one a user returns to by | |
| 838 | + // deselecting their provider (#572). | |
| 839 | + if (!in_array($value, \ThinkRank\Core\Settings::selectable_ai_providers(), true)) { | |
| 853 | 840 | $validation['valid'] = false; |
| 854 | - $validation['errors'][] = "ai_provider must be 'openai', 'claude', 'gemini', or 'openrouter'"; | |
| 841 | + $validation['errors'][] = "ai_provider must be empty (no provider) or one of: " | |
| 842 | + . implode(', ', \ThinkRank\Core\Settings::SUPPORTED_AI_PROVIDERS); | |
| 855 | 843 | } |
| 856 | 844 | break; |
| 857 | 845 | |
| 858 | 846 | case 'dashboard_widgets': |