← All changes
|
includes/abilities/analysis/class-get-integrations-status.php
+69
-12
1.27.0
→
2.7.0
View file →
| @@ -10,8 +10,9 @@ | ||
| 10 | 10 | namespace ThinkRank\Abilities\Analysis; |
| 11 | 11 | |
| 12 | 12 | use ThinkRank\Abilities\Ability_Base; |
| 13 | 13 | use ThinkRank\Core\Settings; |
| 14 | +use ThinkRank\Integrations\Google_PageSpeed_Client; | |
| 14 | 15 | |
| 15 | 16 | if ( ! defined( 'ABSPATH' ) ) { |
| 16 | 17 | exit; // Exit if accessed directly. |
| 17 | 18 | } |
| @@ -30,9 +31,9 @@ | ||
| 30 | 31 | */ |
| 31 | 32 | public function __construct() { |
| 32 | 33 | $this->id = 'thinkrank/get-integrations-status'; |
| 33 | 34 | $this->label = __( 'Get Integrations Status', 'thinkrank' ); |
| 34 | - $this->description = __( 'Report the connection status of the Google Analytics, Search Console, and PageSpeed integrations (connected/configured flags, GA4 measurement ID, selected Search Console site). Never returns API keys or OAuth tokens.', 'thinkrank' ); | |
| 35 | + $this->description = __( 'Report the connection status of the Google Analytics, Search Console, and PageSpeed integrations (connected/configured flags, selected GA4 property, selected Search Console site). Never returns API keys or OAuth tokens.', 'thinkrank' ); | |
| 35 | 36 | } |
| 36 | 37 | |
| 37 | 38 | /** |
| 38 | 39 | * {@inheritDoc} |
| @@ -57,9 +58,9 @@ | ||
| 57 | 58 | public function get_input_schema() { |
| 58 | 59 | return [ |
| 59 | 60 | 'type' => 'object', |
| 60 | 61 | 'additionalProperties' => false, |
| 61 | - 'properties' => [], | |
| 62 | + 'properties' => self::empty_properties(), | |
| 62 | 63 | ]; |
| 63 | 64 | } |
| 64 | 65 | |
| 65 | 66 | /** |
| @@ -96,28 +97,84 @@ | ||
| 96 | 97 | */ |
| 97 | 98 | public function execute( $input ) { |
| 98 | 99 | $settings = Settings::instance(); |
| 99 | 100 | |
| 100 | - // Derive "configured" from presence only — never surface the value itself. | |
| 101 | - $ga_configured = '' !== (string) $settings->get( 'google_analytics_api_key', '' ); | |
| 102 | - $sc_configured = '' !== (string) $settings->get( 'google_search_console_api_key', '' ); | |
| 103 | - $ps_configured = '' !== (string) $settings->get( 'google_pagespeed_api_key', '' ); | |
| 101 | + // "Configured" must mean "this integration can actually make a call", | |
| 102 | + // derived from the SAME conditions the client-initialization code uses. | |
| 103 | + // | |
| 104 | + // It previously keyed off three manual `*_api_key` options that no | |
| 105 | + // current code path writes — the OAuth connect flow stores tokens only | |
| 106 | + // (Google_OAuth_Proxy) and the property pickers store property ids — so | |
| 107 | + // an OAuth-connected site actively serving GA4/GSC/PSI data reported | |
| 108 | + // `configured: false` for all three while the same payload reported | |
| 109 | + // `google_account_connected: true`. The report contradicted itself on | |
| 110 | + // the one thing it exists to answer, which is worse than useless to an | |
| 111 | + // agent deciding whether an integration is available. | |
| 112 | + // | |
| 113 | + // The keys are retained as OR-branches: they are optional for data | |
| 114 | + // retrieval but still honored when present (see | |
| 115 | + // Google_PageSpeed_Client::for_site()). | |
| 104 | 116 | $oauth_present = '' !== (string) $settings->get( 'google_access_token', '' ); |
| 105 | 117 | |
| 118 | + // GA4: Analytics_Manager builds the Data API client only when a token | |
| 119 | + // AND a selected property both exist — mirror that exactly. | |
| 120 | + $ga_property = (string) $settings->get( 'seo_analytics_google_analytics_property_id', '' ); | |
| 121 | + $ga_configured = ( $oauth_present && '' !== $ga_property ) | |
| 122 | + || '' !== (string) $settings->get( 'google_analytics_api_key', '' ); | |
| 123 | + | |
| 124 | + // Search Console: the client authenticates with the token; the API key | |
| 125 | + // is passed as '' on an OAuth site. A property is not required to | |
| 126 | + // construct it (Analytics_Manager falls back to the site URL). | |
| 127 | + $sc_property = (string) $settings->get( 'search_console_property', '' ); | |
| 128 | + $sc_configured = $oauth_present | |
| 129 | + || '' !== (string) $settings->get( 'google_search_console_api_key', '' ); | |
| 130 | + | |
| 131 | + // PageSpeed: for_site() prefers a dedicated key, else the OAuth token, | |
| 132 | + // else runs keyless on the per-IP quota. Report credentialed state, and | |
| 133 | + // read it from the same predicate the Performance tab gates on, so the | |
| 134 | + // two screens cannot disagree about the same site again (#519). | |
| 135 | + $ps_key = (string) $settings->get( 'google_pagespeed_api_key', '' ); | |
| 136 | + $ps_configured = Google_PageSpeed_Client::site_has_credentials(); | |
| 137 | + | |
| 138 | + $google_analytics = [ | |
| 139 | + 'configured' => $ga_configured, | |
| 140 | + // The selected GA4 property, in the Admin API's | |
| 141 | + // "properties/XXXXXXXX" form. Empty means no property picked, | |
| 142 | + // which is the usual reason GA is connected but unusable. | |
| 143 | + 'property_id' => $ga_property, | |
| 144 | + ]; | |
| 145 | + | |
| 146 | + /** | |
| 147 | + * Filters the google_analytics block of the integrations status. | |
| 148 | + * | |
| 149 | + * ThinkRank Pro, which installs the GA4 tag, adds its state here as | |
| 150 | + * `tag_injection`. That describes the tag Pro prints, not whether the | |
| 151 | + * site has a working GA4 tag (#250); `configured` answers whether | |
| 152 | + * ThinkRank can read Analytics data. | |
| 153 | + * | |
| 154 | + * @since 2.6.0 | |
| 155 | + * | |
| 156 | + * @param array<string, mixed> $google_analytics Status block. | |
| 157 | + */ | |
| 158 | + $filtered = apply_filters( 'thinkrank_integrations_status_google_analytics', $google_analytics ); | |
| 159 | + | |
| 106 | 160 | return [ |
| 107 | 161 | 'google_account_connected' => (bool) $settings->get( 'google_account_connected', false ), |
| 108 | - 'google_analytics' => [ | |
| 109 | - 'configured' => $ga_configured, | |
| 110 | - 'measurement_id' => (string) $settings->get( 'ga4_measurement_id', '' ), | |
| 111 | - 'tracking_verified' => (bool) $settings->get( 'ga4_tracking_verified', false ), | |
| 112 | - ], | |
| 162 | + 'google_analytics' => is_array( $filtered ) ? $filtered : $google_analytics, | |
| 113 | 163 | 'search_console' => [ |
| 114 | 164 | 'configured' => $sc_configured, |
| 115 | - 'site' => (string) $settings->get( 'google_search_console_site', '' ), | |
| 165 | + // Was reading `google_search_console_site` — a key with no | |
| 166 | + // writer anywhere in the plugin (only two disconnect paths | |
| 167 | + // clear it), so this was unconditionally ''. The property | |
| 168 | + // picker writes `search_console_property`. | |
| 169 | + 'site' => $sc_property, | |
| 116 | 170 | ], |
| 117 | 171 | 'pagespeed' => [ |
| 118 | 172 | 'configured' => $ps_configured, |
| 119 | 173 | 'oauth_connected' => $oauth_present, |
| 174 | + // Distinguishes "own key, own quota" from "shared OAuth quota" | |
| 175 | + // — the difference between reliable and 429-prone PSI runs. | |
| 176 | + 'has_api_key' => '' !== $ps_key, | |
| 120 | 177 | ], |
| 121 | 178 | ]; |
| 122 | 179 | } |
| 123 | 180 | } |