get_opts(); $client_id = $o['gsc_client_id'] ?? ''; $client_secret = $o['gsc_client_secret'] ?? ''; $redirect_uri = admin_url( 'tools.php?page=aije-lite&tab=gsc&gsc_callback=1' ); $resp = wp_remote_post( 'https://oauth2.googleapis.com/token', array( 'body' => array( 'code' => sanitize_text_field( $_GET['code'] ), 'client_id' => $client_id, 'client_secret' => $client_secret, 'redirect_uri' => $redirect_uri, 'grant_type' => 'authorization_code' ), ) ); if ( ! is_wp_error( $resp ) ) { $token = json_decode( wp_remote_retrieve_body( $resp ), true ); if ( ! empty( $token['access_token'] ) ) { update_option( 'aije_gsc_access_token', $token['access_token'] ); update_option( 'aije_gsc_refresh_token', $token['refresh_token'] ?? '' ); update_option( 'aije_gsc_token_expiry', time() + ( $token['expires_in'] ?? 3600 ) ); wp_safe_redirect( admin_url( 'tools.php?page=aije-lite&tab=gsc&gsc_connected=1' ) ); exit; } } wp_safe_redirect( admin_url( 'tools.php?page=aije-lite&tab=gsc&gsc_error=1' ) ); exit; } if ( isset( $_GET['gsc_disconnect'] ) ) { delete_option( 'aije_gsc_access_token' ); delete_option( 'aije_gsc_refresh_token' ); delete_option( 'aije_gsc_token_expiry' ); wp_safe_redirect( admin_url( 'tools.php?page=aije-lite&tab=gsc' ) ); exit; } } private function refresh_gsc_token() { $o = $this->get_opts(); $client_id = $o['gsc_client_id'] ?? ''; $client_secret = $o['gsc_client_secret'] ?? ''; $refresh_token = get_option( 'aije_gsc_refresh_token', '' ); if ( ! $refresh_token || ! $client_id || ! $client_secret ) { return false; } $resp = wp_remote_post( 'https://oauth2.googleapis.com/token', array( 'body' => array( 'client_id' => $client_id, 'client_secret' => $client_secret, 'refresh_token' => $refresh_token, 'grant_type' => 'refresh_token' ), 'timeout' => 10 ) ); if ( is_wp_error( $resp ) ) { return false; } $token = json_decode( wp_remote_retrieve_body( $resp ), true ); if ( empty( $token['access_token'] ) ) { return false; } update_option( 'aije_gsc_access_token', $token['access_token'] ); update_option( 'aije_gsc_token_expiry', time() + ( $token['expires_in'] ?? 3600 ) ); return $token['access_token']; } private function get_valid_gsc_token() { $access_token = get_option( 'aije_gsc_access_token', '' ); $expiry = (int) get_option( 'aije_gsc_token_expiry', 0 ); if ( $expiry && time() > $expiry - 300 ) { $new_token = $this->refresh_gsc_token(); if ( $new_token ) { return $new_token; } delete_option( 'aije_gsc_access_token' ); return ''; } return $access_token; } /** * Ruft GSC Search Analytics ab und gibt Rohdaten zurück. * Wird von tab-gsc.php (Seitenansicht) und render_gsc_data() genutzt. */ private function gsc_query( $access_token, $property, $body_array, $timeout = 15 ) { $resp = wp_remote_post( 'https://www.googleapis.com/webmasters/v3/sites/' . urlencode( $property ) . '/searchAnalytics/query', array( 'headers' => array( 'Authorization' => 'Bearer ' . $access_token, 'Content-Type' => 'application/json' ), 'body' => wp_json_encode( $body_array ), 'timeout' => $timeout ) ); if ( is_wp_error( $resp ) ) { return array(); } return json_decode( wp_remote_retrieve_body( $resp ), true )['rows'] ?? array(); } private function gsc_get_sites( $access_token ) { $resp = wp_remote_get( 'https://www.googleapis.com/webmasters/v3/sites', array( 'headers' => array( 'Authorization' => 'Bearer ' . $access_token ), 'timeout' => 10 ) ); if ( is_wp_error( $resp ) ) { return array(); } if ( wp_remote_retrieve_response_code( $resp ) === 401 ) { $new = $this->refresh_gsc_token(); if ( ! $new ) { delete_option( 'aije_gsc_access_token' ); return array(); } $resp = wp_remote_get( 'https://www.googleapis.com/webmasters/v3/sites', array( 'headers' => array( 'Authorization' => 'Bearer ' . $new ), 'timeout' => 10 ) ); if ( is_wp_error( $resp ) ) { return array(); } } return json_decode( wp_remote_retrieve_body( $resp ), true )['siteEntry'] ?? array(); } /** * Rendert die GSC-Datentabelle (aufgerufen aus tab-gsc.php wenn verbunden). */ private function render_gsc_data( $access_token ) { $access_token = $this->get_valid_gsc_token(); if ( ! $access_token ) { echo '
⚠ Google Token abgelaufen. Bitte Verbindung trennen und neu verbinden.
Keine Search Console Properties gefunden.
'; return; } $selected = get_option( 'aije_gsc_property', $entries[0]['siteUrl'] ?? '' ); if ( isset( $_POST['gsc_property'] ) ) { $selected = sanitize_text_field( $_POST['gsc_property'] ); update_option( 'aije_gsc_property', $selected ); } // Property-Auswahl echo 'Keine Daten gefunden.
'; return; } // KPI-Zeile $total_clicks = array_sum( array_column( $rows, 'clicks' ) ); $total_impr = array_sum( array_column( $rows, 'impressions' ) ); $cmp_clicks = array_sum( array_column( $cmp_rows, 'clicks' ) ); $cmp_impr = array_sum( array_column( $cmp_rows, 'impressions' ) ); $ti_avg = $total_impr > 0 ? $total_impr : 1; $w_ctr = 0; $w_pos = 0; foreach ( $rows as $r ) { $iw = ( $r['impressions'] ?? 0 ) / $ti_avg; $w_ctr += ( $r['ctr'] ?? 0 ) * $iw; $w_pos += ( $r['position'] ?? 0 ) * $iw; } $avg_ctr = round( $w_ctr * 100, 1 ); $avg_pos = round( $w_pos, 1 ); $dc = $total_clicks - $cmp_clicks; $di = $total_impr - $cmp_impr; $fmt = function( $v, $inv = false ) { if ( $v == 0 ) return '±0'; $pos = $inv ? $v < 0 : $v > 0; $c = $pos ? '#22c55e' : '#ef4444'; return '' . ( $v > 0 ? '+' : '' ) . round( $v, 1 ) . ''; }; echo '| ' . esc_html( $col[1] ) . ( ! $no_sort ? ' ' : '' ) . ' | '; } echo '||||||
|---|---|---|---|---|---|---|
| ' . ( $task_html ? ' ' . $task_html . ' ' : '✓ OK' ) . ' | ';
echo '' . number_format_i18n( $clicks ) . ' | '; echo '' . $dc_html . ' | '; echo '' . number_format_i18n( $impr ) . ' | '; echo '' . $ctr_raw . '% | '; echo '' . $pos . ' | '; echo '' . $dp_html . ' | '; echo '