provider_manager = $provider_manager; add_action( 'admin_menu', [ $this, 'register_settings_pages' ] ); add_action( 'admin_init', [ $this, 'register_settings' ] ); add_action( 'admin_enqueue_scripts', [ $this, 'enqueue_settings_assets' ] ); add_action( 'admin_head', [ $this, 'hide_menu_links' ] ); add_action( 'admin_post_groq_ai_google_oauth_start', [ $this, 'handle_google_oauth_start' ] ); add_action( 'admin_post_groq_ai_google_oauth_callback', [ $this, 'handle_google_oauth_callback' ] ); add_action( 'admin_post_groq_ai_google_oauth_disconnect', [ $this, 'handle_google_oauth_disconnect' ] ); add_action( 'admin_post_groq_ai_google_test_connection', [ $this, 'handle_google_test_connection' ] ); } public function register_settings_pages() { add_options_page( __( 'Siti AI Productteksten', GROQ_AI_PRODUCT_TEXT_DOMAIN ), __( 'Siti AI', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'manage_options', 'groq-ai-product-text', [ $this, 'render_settings_page' ] ); add_submenu_page( 'options-general.php', __( 'Siti AI Modules', GROQ_AI_PRODUCT_TEXT_DOMAIN ), __( 'Siti AI Modules', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'manage_options', 'groq-ai-product-text-modules', [ $this, 'render_modules_page' ] ); add_submenu_page( 'options-general.php', __( 'Siti AI Prompt instellingen', GROQ_AI_PRODUCT_TEXT_DOMAIN ), __( 'Siti AI Prompt instellingen', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'manage_options', 'groq-ai-product-text-prompts', [ $this, 'render_prompt_settings_page' ] ); } private function get_request_redirect_url( $field, $page_slug = 'groq-ai-product-text' ) { $default = $this->get_page_url( $page_slug ); $value = isset( $_REQUEST[ $field ] ) ? wp_unslash( $_REQUEST[ $field ] ) : ''; if ( '' === $value ) { return $default; } return wp_validate_redirect( $value, $default ); } private function parse_oauth_state( $value ) { $value = (string) $value; if ( '' === $value ) { return []; } $decoded = base64_decode( $value, true ); if ( ! is_string( $decoded ) || '' === $decoded ) { return []; } $data = json_decode( $decoded, true ); return is_array( $data ) ? $data : []; } private function redirect_with_google_notice( $type, $message = '', $redirect = null, $status = 'success' ) { $redirect = $redirect ? $redirect : $this->get_page_url(); $args = [ 'groq_ai_google_notice' => sanitize_key( (string) $type ), 'groq_ai_google_notice_status' => sanitize_key( (string) $status ), ]; if ( '' !== $message ) { $args['groq_ai_google_notice_message'] = rawurlencode( (string) $message ); } wp_safe_redirect( add_query_arg( $args, $redirect ) ); exit; } private function get_google_redirect_uri() { return add_query_arg( 'action', 'groq_ai_google_oauth_callback', admin_url( 'admin-post.php' ) ); } private function update_settings_partial( array $updates ) { $option_key = $this->plugin->get_option_key(); $current = get_option( $option_key, [] ); if ( ! is_array( $current ) ) { $current = []; } foreach ( $updates as $key => $value ) { $current[ $key ] = $value; } update_option( $option_key, $current ); } public function render_settings_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } $option_key = $this->plugin->get_option_key(); $settings = $this->plugin->get_settings(); $providers = $this->provider_manager->get_providers(); $current_page = $this->get_page_url(); $prompt_url = $this->get_page_url( 'groq-ai-product-text-prompts' ); $modules_url = $this->get_page_url( 'groq-ai-product-text-modules' ); $logs_url = $this->get_page_url( 'groq-ai-product-text-logs' ); $categories_url = $this->get_page_url( 'groq-ai-product-text-categories' ); $brands_url = $this->get_page_url( 'groq-ai-product-text-brands' ); $prompt_preview = $this->plugin->build_prompt_template_preview( $settings ); $google_safety_settings = $this->plugin->get_google_safety_settings( $settings ); $google_safety_categories = $this->plugin->get_google_safety_categories(); $google_safety_thresholds = $this->plugin->get_google_safety_thresholds(); $renderer = $this->plugin->create_settings_renderer( $settings ); ?>

open_table(); $provider_options = []; foreach ( $providers as $provider ) { $provider_options[ $provider->get_key() ] = $provider->get_label(); } $renderer->field( [ 'label' => __( 'Aanbieder', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'key' => 'provider', 'type' => 'select', 'options' => $provider_options, 'attributes' => [ 'id' => 'groq-ai-provider', ], 'description' => __( 'Selecteer welke aanbieder de product- en termteksten schrijft.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ] ); $renderer->field( [ 'label' => __( 'Model', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'key' => 'model', 'renderer' => [ $this, 'render_model_select_field' ], 'attributes' => [ 'id' => 'groq-ai-model-select', ], ] ); foreach ( $providers as $provider ) { $provider_key = $provider->get_key(); $option_field = $provider->get_option_key(); $renderer->field( [ 'label' => __( 'API-sleutel', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'key' => $option_field, 'type' => 'password', 'attributes' => [ 'id' => 'groq-ai-api-' . $provider_key, 'class' => 'regular-text', 'autocomplete' => 'off', ], 'row_attributes' => [ 'id' => 'groq_ai_api_key_' . $provider_key, 'data-provider-row' => $provider_key, ], 'description' => sprintf( esc_html__( 'Voer de API-sleutel in voor %s.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), esc_html( $provider->get_label() ) ), 'renderer' => [ $this, 'render_provider_api_key_field' ], 'provider_key' => $provider_key, 'google_safety_categories' => $google_safety_categories, 'google_safety_thresholds' => $google_safety_thresholds, 'google_safety_settings' => $google_safety_settings, ] ); } $renderer->close_table(); ?>

open_table(); $renderer->field( [ 'label' => __( 'Maximale output tokens', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'key' => 'max_output_tokens', 'type' => 'number', 'attributes' => [ 'min' => 128, 'max' => 8192, ], 'description' => __( 'Limitering van het aantal tokens per output voor compatibiliteit met verschillende modellen.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ] ); $renderer->field( [ 'label' => __( 'Logboek retentie (dagen)', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'key' => 'logs_retention_days', 'type' => 'number', 'attributes' => [ 'min' => 0, 'max' => 3650, ], 'description' => __( 'Hoe lang logboekregels bewaard blijven. Zet op 0 om logs onbeperkt te bewaren.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ] ); $renderer->field( [ 'label' => __( 'Term meta key (onderste tekst)', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'key' => 'term_bottom_description_meta_key', 'placeholder' => 'groq_ai_term_bottom_description', 'description' => __( 'Optioneel: overschrijf in welke term meta key de onderste omschrijving moet landen.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ] ); $renderer->field( [ 'label' => __( 'Response format fallback', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'renderer' => function ( $field, $renderer ) { $this->render_response_format_compat_field(); }, ] ); $renderer->close_table(); ?>

plugin->get_option_key(), $this->plugin->get_option_key(), [ $this->plugin, 'sanitize_settings' ] ); } public function hide_menu_links() { if ( ! current_user_can( 'manage_options' ) ) { return; } ?> plugin->get_option_key(); $settings = $this->plugin->get_settings(); $current_page = $this->get_page_url( 'groq-ai-product-text-modules' ); $oauth_redirect = add_query_arg( 'action', 'groq_ai_google_oauth_callback', admin_url( 'admin-post.php' ) ); $google_notice = isset( $_GET['groq_ai_google_notice'] ) ? sanitize_key( wp_unslash( $_GET['groq_ai_google_notice'] ) ) : ''; $google_status = isset( $_GET['groq_ai_google_notice_status'] ) ? sanitize_key( wp_unslash( $_GET['groq_ai_google_notice_status'] ) ) : ''; $google_message = ''; if ( isset( $_GET['groq_ai_google_notice_message'] ) ) { $google_message = sanitize_text_field( rawurldecode( wp_unslash( $_GET['groq_ai_google_notice_message'] ) ) ); } $google_connected = ! empty( $settings['google_oauth_refresh_token'] ); $google_connected_email = isset( $settings['google_oauth_connected_email'] ) ? (string) $settings['google_oauth_connected_email'] : ''; $google_connected_at = isset( $settings['google_oauth_connected_at'] ) ? absint( $settings['google_oauth_connected_at'] ) : 0; ?>

plugin->create_settings_renderer( $settings ); $renderer->open_table(); $renderer->field( [ 'label' => __( 'Google OAuth client ID', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'key' => 'google_oauth_client_id', 'attributes' => [ 'autocomplete' => 'off' ], 'description' => __( 'Stel deze plugin in als OAuth-client in Google Cloud Console en gebruik onderstaande redirect-URL.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ] ); $renderer->field( [ 'label' => __( 'Google OAuth client secret', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'key' => 'google_oauth_client_secret', 'type' => 'password', 'attributes' => [ 'autocomplete' => 'off' ], 'description' => sprintf( '%s
%s', esc_html__( 'Redirect URI voor OAuth (voeg exact zo toe in Google Cloud → Credentials):', GROQ_AI_PRODUCT_TEXT_DOMAIN ), esc_html( $oauth_redirect ) ), ] ); $renderer->field( [ 'label' => __( 'Search Console koppeling', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'type' => 'checkbox', 'key' => 'google_enable_gsc', 'checkbox_label' => __( 'Search Console data gebruiken in term prompts', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'renderer' => function ( $field, $renderer ) use ( $option_key, $settings ) { $value = ! empty( $settings['google_gsc_site_url'] ) ? $settings['google_gsc_site_url'] : ''; printf( '

', esc_attr( $option_key ), esc_attr( $value ) ); }, ] ); $renderer->field( [ 'label' => __( 'Analytics koppeling', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'type' => 'checkbox', 'key' => 'google_enable_ga', 'checkbox_label' => __( 'GA4 data meesturen (landing page statistieken)', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'renderer' => function ( $field, $renderer ) use ( $option_key, $settings ) { $value = ! empty( $settings['google_ga4_property_id'] ) ? $settings['google_ga4_property_id'] : ''; printf( '

', esc_attr( $option_key ), esc_attr( $value ) ); }, ] ); $renderer->close_table(); ?>

plugin->get_option_key(); $settings = $this->plugin->get_settings(); $definitions = $this->plugin->get_context_field_definitions(); $context_vals = isset( $settings['context_fields'] ) ? (array) $settings['context_fields'] : $this->plugin->get_default_context_fields(); $image_mode = $this->plugin->get_image_context_mode( $settings ); $image_limit = $this->plugin->get_image_context_limit( $settings ); $preview = $this->plugin->build_prompt_template_preview( $settings ); $term_top_limit = $this->plugin->get_term_top_description_char_limit( $settings ); $term_bottom_limit = $this->plugin->get_term_bottom_description_char_limit( $settings ); ?>

plugin->get_settings(); $values = isset( $settings['product_attribute_includes'] ) && is_array( $settings['product_attribute_includes'] ) ? $settings['product_attribute_includes'] : []; $values = array_values( array_unique( array_map( 'sanitize_key', $values ) ) ); $options = $this->get_product_attribute_include_options(); ?>

$label ) : $checked = in_array( $key, $values, true ); ?>

', $this->format_html_attributes( $attributes ) ); if ( isset( $field_args['provider_key'] ) && 'google' === $field_args['provider_key'] ) { $this->render_google_safety_fields( $field_args ); } } private function render_google_safety_fields( $field_args ) { $categories = isset( $field_args['google_safety_categories'] ) && is_array( $field_args['google_safety_categories'] ) ? $field_args['google_safety_categories'] : []; $thresholds = isset( $field_args['google_safety_thresholds'] ) && is_array( $field_args['google_safety_thresholds'] ) ? $field_args['google_safety_thresholds'] : []; if ( empty( $categories ) || empty( $thresholds ) ) { return; } $selected_settings = isset( $field_args['google_safety_settings'] ) && is_array( $field_args['google_safety_settings'] ) ? $field_args['google_safety_settings'] : []; $option_key = $this->plugin->get_option_key(); ?>

$info ) : $category_label = isset( $info['label'] ) ? $info['label'] : $category_key; $category_description = isset( $info['description'] ) ? $info['description'] : ''; $selected_threshold = isset( $selected_settings[ $category_key ] ) ? $selected_settings[ $category_key ] : ''; $field_id = 'groq-ai-google-safety-' . sanitize_html_class( $category_key ); ?>
$value ) { if ( '' === $value && 0 !== $value && '0' !== $value ) { continue; } $pairs[] = sprintf( '%s="%s"', esc_attr( $key ), esc_attr( $value ) ); } return implode( ' ', $pairs ); } private function get_product_attribute_include_options() { $options = [ '__custom__' => __( 'Custom attributen (niet-taxonomie)', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ]; if ( function_exists( 'wc_get_attribute_taxonomies' ) ) { $taxonomies = wc_get_attribute_taxonomies(); if ( is_array( $taxonomies ) ) { foreach ( $taxonomies as $attr ) { $name = isset( $attr->attribute_name ) ? sanitize_key( (string) $attr->attribute_name ) : ''; $label = isset( $attr->attribute_label ) ? sanitize_text_field( (string) $attr->attribute_label ) : ''; if ( '' === $name ) { continue; } $taxonomy = 'pa_' . $name; if ( '' === $label ) { $label = function_exists( 'wc_attribute_label' ) ? wc_attribute_label( $taxonomy ) : $taxonomy; } $options[ $taxonomy ] = $label; } } } if ( count( $options ) > 1 ) { $fixed = [ '__custom__' => $options['__custom__'], ]; unset( $options['__custom__'] ); asort( $options, SORT_NATURAL | SORT_FLAG_CASE ); $options = $fixed + $options; } return $options; } public function render_response_format_compat_field() { $settings = $this->plugin->get_settings(); $is_enabled = ! empty( $settings['response_format_compat'] ); ?>

plugin->get_settings(); $defaults = $this->plugin->get_default_modules_settings(); $modules = isset( $settings['modules'] ) ? $settings['modules'] : $defaults; $config = isset( $modules['rankmath'] ) ? $modules['rankmath'] : ( $defaults['rankmath'] ?? [] ); $rankmath_active = $this->plugin->is_rankmath_active(); $enabled = $rankmath_active && ! empty( $config['enabled'] ); $keyword_limit = isset( $config['focus_keyword_limit'] ) ? absint( $config['focus_keyword_limit'] ) : ( $defaults['rankmath']['focus_keyword_limit'] ?? 3 ); $keyword_limit = $keyword_limit > 0 ? $keyword_limit : 3; $title_pixels = isset( $config['meta_title_pixel_limit'] ) ? absint( $config['meta_title_pixel_limit'] ) : ( $defaults['rankmath']['meta_title_pixel_limit'] ?? 580 ); $title_pixels = $title_pixels > 0 ? $title_pixels : 580; $pixel_limit = isset( $config['meta_description_pixel_limit'] ) ? absint( $config['meta_description_pixel_limit'] ) : ( $defaults['rankmath']['meta_description_pixel_limit'] ?? 920 ); $pixel_limit = $pixel_limit > 0 ? $pixel_limit : 920; $rankmath_active = $this->plugin->is_rankmath_active(); ?>

/>

/>

/>

enqueue_admin_styles(); $current_page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : ''; $is_main_settings_screen = ( 0 === strpos( (string) $hook, 'settings_page_groq-ai-product-text' ) ) && ( 'groq-ai-product-text' === $current_page ); if ( ! $is_main_settings_screen ) { return; } wp_enqueue_script( 'groq-ai-settings', plugins_url( 'assets/js/settings.js', GROQ_AI_PRODUCT_TEXT_FILE ), [], GROQ_AI_PRODUCT_TEXT_VERSION, true ); $current_settings = $this->plugin->get_settings(); $data = [ 'optionKey' => $this->plugin->get_option_key(), 'providers' => [], 'currentProvider' => $current_settings['provider'], 'currentModel' => $current_settings['model'], 'providerRows' => [], 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'refreshNonce' => wp_create_nonce( 'groq_ai_refresh_models' ), 'excludedModels' => Groq_AI_Model_Exclusions::get_all(), 'placeholders' => [ 'selectModel' => __( 'Selecteer een model via "Live modellen ophalen"', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ], 'strings' => [ 'providerUnsupported' => __( 'Deze aanbieder ondersteunt dit niet.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'apiKeyRequired' => __( 'Vul eerst de API-sleutel in.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'loadingModels' => __( 'Modellen worden opgehaald…', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'errorUnknown' => __( 'Onbekende fout', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'successModels' => __( 'Modellen bijgewerkt.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'errorFetch' => __( 'Ophalen mislukt.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ], ]; foreach ( $this->provider_manager->get_providers() as $provider ) { $provider_key = $provider->get_key(); $cached_models = $this->plugin->get_cached_models_for_provider( $provider_key ); $cached_models = Groq_AI_Model_Exclusions::filter_models( $provider_key, $cached_models ); $data['providers'][ $provider_key ] = [ 'default_label' => sprintf( __( 'Gebruik standaardmodel (%s)', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $provider->get_default_model() ), 'models' => $cached_models, 'supports_live' => $provider->supports_live_models(), ]; $data['providerRows'][ $provider_key ] = 'groq_ai_api_key_' . $provider_key; } wp_localize_script( 'groq-ai-settings', 'GroqAISettingsData', $data ); } public function handle_google_oauth_start() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Je hebt geen toestemming om deze actie uit te voeren.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), '', [ 'response' => 403 ] ); } check_admin_referer( 'groq_ai_google_oauth' ); $redirect = $this->get_request_redirect_url( 'redirect_to' ); $settings = $this->plugin->get_settings(); $client_id = isset( $settings['google_oauth_client_id'] ) ? trim( (string) $settings['google_oauth_client_id'] ) : ''; $client_secret = isset( $settings['google_oauth_client_secret'] ) ? trim( (string) $settings['google_oauth_client_secret'] ) : ''; if ( '' === $client_id || '' === $client_secret ) { $this->redirect_with_google_notice( 'error', __( 'Vul eerst het Google client ID en secret in en sla de instellingen op.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $redirect, 'error' ); } $state_payload = [ 'nonce' => wp_create_nonce( 'groq_ai_google_oauth_state' ), 'redirect' => $redirect, 'timestamp' => time(), ]; $state_json = wp_json_encode( $state_payload ); if ( ! is_string( $state_json ) ) { $state_json = wp_json_encode( (object) [] ); } $state = base64_encode( (string) $state_json ); $scopes = [ 'https://www.googleapis.com/auth/webmasters.readonly', 'https://www.googleapis.com/auth/analytics.readonly', 'https://www.googleapis.com/auth/userinfo.email', ]; $auth_url = add_query_arg( [ 'response_type' => 'code', 'client_id' => $client_id, 'redirect_uri' => $this->get_google_redirect_uri(), 'scope' => implode( ' ', $scopes ), 'access_type' => 'offline', 'prompt' => 'consent', 'include_granted_scopes' => 'true', 'state' => $state, ], 'https://accounts.google.com/o/oauth2/v2/auth' ); wp_safe_redirect( $auth_url ); exit; } public function handle_google_oauth_callback() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Je hebt geen toestemming om deze actie uit te voeren.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), '', [ 'response' => 403 ] ); } $state_value = isset( $_GET['state'] ) ? wp_unslash( $_GET['state'] ) : ''; $state = $this->parse_oauth_state( $state_value ); $redirect = isset( $state['redirect'] ) ? wp_validate_redirect( (string) $state['redirect'], $this->get_page_url() ) : $this->get_page_url(); if ( isset( $_GET['error'] ) ) { $error_message = sanitize_text_field( wp_unslash( $_GET['error'] ) ); if ( isset( $_GET['error_description'] ) ) { $error_message .= ': ' . sanitize_text_field( wp_unslash( $_GET['error_description'] ) ); } $this->redirect_with_google_notice( 'error', $error_message, $redirect, 'error' ); } if ( isset( $state['nonce'] ) && ! wp_verify_nonce( $state['nonce'], 'groq_ai_google_oauth_state' ) ) { $this->redirect_with_google_notice( 'error', __( 'Ongeldige OAuth-sessie. Probeer het opnieuw.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $redirect, 'error' ); } $timestamp = isset( $state['timestamp'] ) ? absint( $state['timestamp'] ) : 0; if ( $timestamp && ( time() - $timestamp ) > HOUR_IN_SECONDS ) { $this->redirect_with_google_notice( 'error', __( 'OAuth-sessie verlopen. Probeer het opnieuw.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $redirect, 'error' ); } $code = isset( $_GET['code'] ) ? sanitize_text_field( wp_unslash( $_GET['code'] ) ) : ''; if ( '' === $code ) { $this->redirect_with_google_notice( 'error', __( 'Geen autorisatiecode ontvangen.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $redirect, 'error' ); } $settings = $this->plugin->get_settings(); $client_id = isset( $settings['google_oauth_client_id'] ) ? trim( (string) $settings['google_oauth_client_id'] ) : ''; $client_secret = isset( $settings['google_oauth_client_secret'] ) ? trim( (string) $settings['google_oauth_client_secret'] ) : ''; if ( '' === $client_id || '' === $client_secret ) { $this->redirect_with_google_notice( 'error', __( 'Google client ID en secret ontbreken.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $redirect, 'error' ); } $response = wp_remote_post( 'https://oauth2.googleapis.com/token', [ 'timeout' => 20, 'body' => [ 'code' => $code, 'client_id' => $client_id, 'client_secret' => $client_secret, 'redirect_uri' => $this->get_google_redirect_uri(), 'grant_type' => 'authorization_code', ], ] ); if ( is_wp_error( $response ) ) { $this->redirect_with_google_notice( 'error', $response->get_error_message(), $redirect, 'error' ); } $status_code = wp_remote_retrieve_response_code( $response ); $body = wp_remote_retrieve_body( $response ); $data = json_decode( (string) $body, true ); if ( 200 !== $status_code || ! is_array( $data ) ) { $this->redirect_with_google_notice( 'error', __( 'Kon tokens niet ophalen bij Google.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $redirect, 'error' ); } $access_token = isset( $data['access_token'] ) ? trim( (string) $data['access_token'] ) : ''; $refresh_token = isset( $data['refresh_token'] ) ? trim( (string) $data['refresh_token'] ) : ''; if ( '' === $refresh_token ) { $existing = isset( $settings['google_oauth_refresh_token'] ) ? (string) $settings['google_oauth_refresh_token'] : ''; $refresh_token = $existing; } if ( '' === $refresh_token ) { $this->redirect_with_google_notice( 'error', __( 'Google retourneerde geen refresh token. Forceer toestemming opnieuw en probeer het nogmaals.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $redirect, 'error' ); } if ( '' === $access_token ) { $this->redirect_with_google_notice( 'error', __( 'Google retourneerde geen access token.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $redirect, 'error' ); } $email = ''; $userinfo = wp_remote_get( 'https://openidconnect.googleapis.com/v1/userinfo', [ 'timeout' => 15, 'headers' => [ 'Authorization' => 'Bearer ' . $access_token, ], ] ); if ( ! is_wp_error( $userinfo ) ) { $userinfo_code = wp_remote_retrieve_response_code( $userinfo ); $userinfo_body = json_decode( wp_remote_retrieve_body( $userinfo ), true ); if ( 200 === $userinfo_code && is_array( $userinfo_body ) && isset( $userinfo_body['email'] ) ) { $email = sanitize_email( (string) $userinfo_body['email'] ); } } $this->update_settings_partial( [ 'google_oauth_refresh_token' => sanitize_text_field( $refresh_token ), 'google_oauth_connected_email' => $email, 'google_oauth_connected_at' => current_time( 'timestamp' ), ] ); $this->redirect_with_google_notice( 'connected', __( 'Google OAuth is verbonden.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $redirect ); } public function handle_google_oauth_disconnect() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Je hebt geen toestemming om deze actie uit te voeren.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), '', [ 'response' => 403 ] ); } check_admin_referer( 'groq_ai_google_disconnect' ); $redirect = $this->get_request_redirect_url( 'redirect_to' ); $this->update_settings_partial( [ 'google_oauth_refresh_token' => '', 'google_oauth_connected_email' => '', 'google_oauth_connected_at' => 0, ] ); $this->redirect_with_google_notice( 'disconnected', __( 'Google OAuth is ontkoppeld.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $redirect ); } public function handle_google_test_connection() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Je hebt geen toestemming om deze actie uit te voeren.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), '', [ 'response' => 403 ] ); } check_admin_referer( 'groq_ai_google_test_connection' ); $redirect = $this->get_request_redirect_url( 'redirect_to' ); $settings = $this->plugin->get_settings(); $oauth_client = new Groq_AI_Google_OAuth_Client(); $token = $oauth_client->get_access_token( $settings ); if ( is_wp_error( $token ) ) { $this->redirect_with_google_notice( 'test', $token->get_error_message(), $redirect, 'error' ); } $messages = [ __( 'OAuth token opgehaald.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) ]; $token_info = $oauth_client->get_access_token_info( $token ); if ( ! is_wp_error( $token_info ) && ! empty( $token_info['scope'] ) ) { $messages[] = sprintf( __( 'Scopes: %s', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $token_info['scope'] ); } if ( ! empty( $settings['google_enable_gsc'] ) && ! empty( $settings['google_gsc_site_url'] ) ) { $gsc_client = new Groq_AI_Google_Search_Console_Client( $oauth_client ); $result = $gsc_client->list_sites( $settings ); if ( is_wp_error( $result ) ) { $this->redirect_with_google_notice( 'test', $result->get_error_message(), $redirect, 'error' ); } $messages[] = __( 'Search Console API bereikbaar.', GROQ_AI_PRODUCT_TEXT_DOMAIN ); } if ( ! empty( $settings['google_enable_ga'] ) && ! empty( $settings['google_ga4_property_id'] ) ) { $ga_client = new Groq_AI_Google_Analytics_Data_Client( $oauth_client ); $end_date = gmdate( 'Y-m-d' ); $start_date = gmdate( 'Y-m-d', time() - ( 7 * DAY_IN_SECONDS ) ); $summary = $ga_client->get_property_sessions_summary( $settings, $settings['google_ga4_property_id'], $start_date, $end_date ); if ( is_wp_error( $summary ) ) { $this->redirect_with_google_notice( 'test', $summary->get_error_message(), $redirect, 'error' ); } $sessions = isset( $summary['sessions'] ) ? absint( $summary['sessions'] ) : 0; $messages[] = sprintf( __( 'GA4 API bereikbaar (sessies laatste 7 dagen: %d).', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $sessions ); } $this->redirect_with_google_notice( 'test', implode( ' ', $messages ), $redirect ); } }