plugin = $plugin; $this->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_save_term_content', [ $this, 'handle_save_term_content' ] ); 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 Categorie teksten', GROQ_AI_PRODUCT_TEXT_DOMAIN ), __( 'Siti AI Categorieën', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'manage_options', 'groq-ai-product-text-categories', [ $this, 'render_categories_overview_page' ] ); add_submenu_page( 'options-general.php', __( 'Siti AI Merk teksten', GROQ_AI_PRODUCT_TEXT_DOMAIN ), __( 'Siti AI Merken', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'manage_options', 'groq-ai-product-text-brands', [ $this, 'render_brands_overview_page' ] ); add_submenu_page( 'options-general.php', __( 'Siti AI Term tekst', GROQ_AI_PRODUCT_TEXT_DOMAIN ), __( 'Siti AI Term tekst', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'manage_options', 'groq-ai-product-text-term', [ $this, 'render_term_generator_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 AI-logboek', GROQ_AI_PRODUCT_TEXT_DOMAIN ), __( 'Siti AI AI-logboek', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'manage_options', 'groq-ai-product-text-logs', [ $this, 'render_logs_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' ] ); } public function hide_menu_links() { if ( ! current_user_can( 'manage_options' ) ) { return; } ?> brand_taxonomy ) { return $this->brand_taxonomy; } $candidates = [ 'product_brand', 'pwb-brand', 'yith_product_brand', 'berocket_brand', ]; // Attribute-taxonomy fallback (vaak pa_brand). if ( taxonomy_exists( 'pa_brand' ) ) { array_unshift( $candidates, 'pa_brand' ); } $candidates = apply_filters( 'groq_ai_brand_taxonomy_candidates', $candidates ); $found = ''; foreach ( $candidates as $tax ) { $tax = sanitize_key( (string) $tax ); if ( $tax && taxonomy_exists( $tax ) ) { $found = $tax; break; } } $found = apply_filters( 'groq_ai_brand_taxonomy', $found ); $this->brand_taxonomy = sanitize_key( (string) $found ); return $this->brand_taxonomy; } private function get_term_page_url( $taxonomy, $term_id ) { return add_query_arg( [ 'page' => 'groq-ai-product-text-term', 'taxonomy' => sanitize_key( (string) $taxonomy ), 'term_id' => absint( $term_id ), ], admin_url( 'options-general.php' ) ); } public function render_categories_overview_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } $terms = get_terms( [ 'taxonomy' => 'product_cat', 'hide_empty' => false, 'orderby' => 'name', 'order' => 'ASC', 'number' => 0, ] ); if ( is_wp_error( $terms ) ) { $terms = []; } $word_map = []; $empty_terms = []; foreach ( $terms as $term ) { if ( ! $term || ! is_object( $term ) ) { continue; } $word_count = $this->count_words( isset( $term->description ) ? $term->description : '' ); $word_map[ $term->term_id ] = $word_count; if ( 0 === $word_count ) { $empty_terms[] = $term; } } ?>
| name ); ?> | slug ); ?> | ||
| name ); ?> | slug ); ?> | ||
-tags. Voeg geen prijsinformatie toe.', GROQ_AI_PRODUCT_TEXT_DOMAIN ); return apply_filters( 'groq_ai_default_term_prompt', $default_prompt, $term ); } private function get_terms_without_description_payload( $taxonomy ) { $terms = get_terms( [ 'taxonomy' => $taxonomy, 'hide_empty' => false, 'orderby' => 'name', 'order' => 'ASC', 'number' => 0, ] ); if ( is_wp_error( $terms ) ) { return []; } $payloads = []; foreach ( $terms as $term ) { $description = isset( $term->description ) ? trim( wp_strip_all_tags( (string) $term->description ) ) : ''; if ( '' !== $description ) { continue; } $payloads[] = [ 'id' => isset( $term->term_id ) ? absint( $term->term_id ) : 0, 'name' => isset( $term->name ) ? (string) $term->name : '', 'slug' => isset( $term->slug ) ? (string) $term->slug : '', 'count' => isset( $term->count ) ? absint( $term->count ) : 0, 'url' => esc_url( $this->get_term_page_url( $taxonomy, isset( $term->term_id ) ? $term->term_id : 0 ) ), ]; } return array_values( $payloads ); } public function handle_save_term_content() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Geen toestemming.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) ); } check_admin_referer( 'groq_ai_save_term_content' ); $taxonomy = isset( $_POST['taxonomy'] ) ? sanitize_key( wp_unslash( $_POST['taxonomy'] ) ) : ''; $term_id = isset( $_POST['term_id'] ) ? absint( $_POST['term_id'] ) : 0; $description = isset( $_POST['description'] ) ? wp_kses_post( wp_unslash( $_POST['description'] ) ) : ''; $bottom_description = isset( $_POST['groq_ai_term_bottom_description'] ) ? wp_kses_post( wp_unslash( $_POST['groq_ai_term_bottom_description'] ) ) : ''; $custom_prompt = isset( $_POST['groq_ai_term_custom_prompt'] ) ? sanitize_textarea_field( wp_unslash( $_POST['groq_ai_term_custom_prompt'] ) ) : ''; $rankmath_meta_title = isset( $_POST['groq_ai_rankmath_meta_title'] ) ? sanitize_text_field( wp_unslash( $_POST['groq_ai_rankmath_meta_title'] ) ) : ''; $rankmath_meta_description = isset( $_POST['groq_ai_rankmath_meta_description'] ) ? sanitize_text_field( wp_unslash( $_POST['groq_ai_rankmath_meta_description'] ) ) : ''; $rankmath_focus_keywords = isset( $_POST['groq_ai_rankmath_focus_keywords'] ) ? sanitize_text_field( wp_unslash( $_POST['groq_ai_rankmath_focus_keywords'] ) ) : ''; if ( '' === $taxonomy || ! taxonomy_exists( $taxonomy ) || ! $term_id ) { wp_safe_redirect( $this->get_settings_page_url() ); exit; } $result = wp_update_term( $term_id, $taxonomy, [ 'description' => $description, ] ); if ( ! is_wp_error( $result ) ) { update_term_meta( $term_id, 'groq_ai_term_custom_prompt', $custom_prompt ); $settings = $this->plugin->get_settings(); $term = get_term( $term_id, $taxonomy ); if ( $term && ! is_wp_error( $term ) ) { $bottom_meta_key = $this->resolve_term_bottom_description_meta_key( $term, $settings ); $effective_bottom_meta_key = '' !== $bottom_meta_key ? $bottom_meta_key : 'groq_ai_term_bottom_description'; update_term_meta( $term_id, $effective_bottom_meta_key, $bottom_description ); $rankmath_module_enabled = $this->plugin->is_module_enabled( 'rankmath', $settings ); if ( $rankmath_module_enabled ) { $rankmath_keys = $this->resolve_rankmath_term_meta_keys( $term, $settings ); update_term_meta( $term_id, $rankmath_keys['title'], $rankmath_meta_title ); update_term_meta( $term_id, $rankmath_keys['description'], $rankmath_meta_description ); update_term_meta( $term_id, $rankmath_keys['focus_keyword'], $rankmath_focus_keywords ); } } } wp_safe_redirect( $this->get_term_page_url( $taxonomy, $term_id ) ); exit; } public function register_settings() { register_setting( 'groq_ai_product_text_group', $this->plugin->get_option_key(), [ $this->plugin, 'sanitize_settings' ] ); add_settings_section( 'groq_ai_product_text_general', __( 'Algemene instellingen', GROQ_AI_PRODUCT_TEXT_DOMAIN ), '__return_false', 'groq-ai-product-text' ); add_settings_section( 'groq_ai_product_text_google', __( 'Google koppeling (OAuth)', GROQ_AI_PRODUCT_TEXT_DOMAIN ), '__return_false', 'groq-ai-product-text' ); add_settings_field( 'groq_ai_provider', __( 'AI-aanbieder', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_provider_field' ], 'groq-ai-product-text', 'groq_ai_product_text_general' ); add_settings_field( 'groq_ai_model', __( 'Model', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_model_field' ], 'groq-ai-product-text', 'groq_ai_product_text_general' ); add_settings_field( 'groq_ai_google_oauth_client_id', __( 'Google Client ID', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_google_oauth_client_id_field' ], 'groq-ai-product-text', 'groq_ai_product_text_google' ); add_settings_field( 'groq_ai_google_oauth_client_secret', __( 'Google Client secret', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_google_oauth_client_secret_field' ], 'groq-ai-product-text', 'groq_ai_product_text_google' ); add_settings_field( 'groq_ai_google_oauth_status', __( 'Google status', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_google_oauth_status_field' ], 'groq-ai-product-text', 'groq_ai_product_text_google' ); add_settings_field( 'groq_ai_google_gsc_site_url', __( 'Search Console site URL', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_google_gsc_site_url_field' ], 'groq-ai-product-text', 'groq_ai_product_text_google' ); add_settings_field( 'groq_ai_google_ga4_property_id', __( 'GA4 property ID', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_google_ga4_property_id_field' ], 'groq-ai-product-text', 'groq_ai_product_text_google' ); add_settings_field( 'groq_ai_google_context_toggles', __( 'Google data gebruiken', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_google_context_toggles_field' ], 'groq-ai-product-text', 'groq_ai_product_text_google' ); foreach ( $this->provider_manager->get_providers() as $provider ) { add_settings_field( 'groq_ai_api_key_' . $provider->get_key(), sprintf( __( '%s API-sleutel', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $provider->get_label() ), [ $this, 'render_provider_api_key_field' ], 'groq-ai-product-text', 'groq_ai_product_text_general', [ 'provider' => $provider, ] ); } add_settings_section( 'groq_ai_product_text_prompts', __( 'Prompt instellingen', GROQ_AI_PRODUCT_TEXT_DOMAIN ), '__return_false', 'groq-ai-product-text-prompts' ); add_settings_field( 'groq_ai_store_context', __( 'Winkelcontext', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_store_context_field' ], 'groq-ai-product-text-prompts', 'groq_ai_product_text_prompts' ); add_settings_field( 'groq_ai_default_prompt', __( 'Standaard prompt', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_default_prompt_field' ], 'groq-ai-product-text-prompts', 'groq_ai_product_text_prompts' ); add_settings_field( 'groq_ai_max_output_tokens', __( 'Max output tokens', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_max_output_tokens_field' ], 'groq-ai-product-text-prompts', 'groq_ai_product_text_prompts' ); add_settings_field( 'groq_ai_term_bottom_description_meta_key', __( 'Term-veld (onderaan) meta key', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_term_bottom_description_meta_key_field' ], 'groq-ai-product-text-prompts', 'groq_ai_product_text_prompts' ); add_settings_field( 'groq_ai_context_fields', __( 'Standaard productcontext', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_context_fields_field' ], 'groq-ai-product-text-prompts', 'groq_ai_product_text_prompts' ); add_settings_field( 'groq_ai_product_attribute_includes', __( 'Productattributen meesturen', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_product_attribute_includes_field' ], 'groq-ai-product-text-prompts', 'groq_ai_product_text_prompts' ); add_settings_field( 'groq_ai_response_format_compat', __( 'Response-format compatibiliteit', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_response_format_compat_field' ], 'groq-ai-product-text-prompts', 'groq_ai_product_text_prompts' ); add_settings_field( 'groq_ai_image_context_mode', __( 'Afbeeldingen toevoegen', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_image_context_mode_field' ], 'groq-ai-product-text-prompts', 'groq_ai_product_text_prompts' ); add_settings_field( 'groq_ai_image_context_limit', __( 'Maximaal aantal afbeeldingen', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_image_context_limit_field' ], 'groq-ai-product-text-prompts', 'groq_ai_product_text_prompts' ); add_settings_section( 'groq_ai_product_text_modules_rankmath', __( 'Rank Math SEO', GROQ_AI_PRODUCT_TEXT_DOMAIN ), '__return_false', 'groq-ai-product-text-modules' ); add_settings_field( 'groq_ai_module_rankmath', __( 'Rank Math SEO', GROQ_AI_PRODUCT_TEXT_DOMAIN ), [ $this, 'render_rankmath_module_field' ], 'groq-ai-product-text-modules', 'groq_ai_product_text_modules_rankmath' ); } public function render_image_context_mode_field() { $settings = $this->plugin->get_settings(); $mode = isset( $settings['image_context_mode'] ) ? $settings['image_context_mode'] : 'url'; $options = [ 'none' => __( 'Nee, geen afbeeldingen', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'url' => __( 'Ja, voeg afbeeldings-URL’s toe aan de prompt', GROQ_AI_PRODUCT_TEXT_DOMAIN ), 'base64' => __( 'Ja, verstuur afbeeldingen als Base64 (indien ondersteund)', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ]; ?>
plugin->get_settings(); $limit = $this->plugin->get_image_context_limit( $settings ); ?>
plugin->get_settings(); ?>
plugin->get_settings(); $value = isset( $settings['google_oauth_client_secret'] ) ? $settings['google_oauth_client_secret'] : ''; ?>
plugin->get_settings(); $connected = ! empty( $settings['google_oauth_refresh_token'] ); $email = isset( $settings['google_oauth_connected_email'] ) ? $settings['google_oauth_connected_email'] : ''; $connected_at = isset( $settings['google_oauth_connected_at'] ) ? absint( $settings['google_oauth_connected_at'] ) : 0; $redirect_uri = $this->get_google_oauth_redirect_uri(); $start_url = wp_nonce_url( admin_url( 'admin-post.php?action=groq_ai_google_oauth_start' ), 'groq_ai_google_oauth_start', '_wpnonce' ); $disconnect_url = wp_nonce_url( admin_url( 'admin-post.php?action=groq_ai_google_oauth_disconnect' ), 'groq_ai_google_oauth_disconnect', '_wpnonce' ); ?>
— ()
plugin->get_settings(); $messages = []; $status = 'success'; $oauth = new Groq_AI_Google_OAuth_Client(); $token = $oauth->get_access_token( $settings ); if ( is_wp_error( $token ) ) { $status = 'error'; $messages[] = sprintf( __( 'OAuth: %s', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $token->get_error_message() ); } else { $messages[] = __( 'OAuth: OK (access token opgehaald).', GROQ_AI_PRODUCT_TEXT_DOMAIN ); $info = $oauth->get_access_token_info( $token ); if ( is_array( $info ) ) { $scope = isset( $info['scope'] ) ? trim( (string) $info['scope'] ) : ''; if ( '' !== $scope ) { $messages[] = sprintf( __( 'OAuth scopes: %s', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $scope ); if ( false === strpos( $scope, 'https://www.googleapis.com/auth/webmasters' ) ) { $messages[] = __( 'Tip: je access token mist Search Console scope. Klik op "Opnieuw verbinden" zodat je toestemming opnieuw wordt gevraagd.', GROQ_AI_PRODUCT_TEXT_DOMAIN ); } } } } $range_days = 7; $end_date = gmdate( 'Y-m-d' ); $start_date = gmdate( 'Y-m-d', time() - ( $range_days * DAY_IN_SECONDS ) ); if ( 'error' !== $status && ! empty( $settings['google_enable_gsc'] ) ) { $gsc = new Groq_AI_Google_Search_Console_Client( $oauth ); $sites = $gsc->list_sites( $settings ); if ( is_wp_error( $sites ) ) { $status = 'error'; $messages[] = sprintf( __( 'Search Console: %s', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $sites->get_error_message() ); } else { $count = is_array( $sites ) ? count( $sites ) : 0; $messages[] = sprintf( __( 'Search Console: OK (%d properties zichtbaar).', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $count ); $site_url = isset( $settings['google_gsc_site_url'] ) ? trim( (string) $settings['google_gsc_site_url'] ) : ''; if ( '' !== $site_url && is_array( $sites ) && ! in_array( $site_url, $sites, true ) ) { $messages[] = __( 'Let op: de ingestelde site URL is niet gevonden in jouw zichtbare GSC properties.', GROQ_AI_PRODUCT_TEXT_DOMAIN ); } } } if ( 'error' !== $status && ! empty( $settings['google_enable_ga'] ) ) { $property_id = isset( $settings['google_ga4_property_id'] ) ? trim( (string) $settings['google_ga4_property_id'] ) : ''; if ( '' !== $property_id ) { $ga = new Groq_AI_Google_Analytics_Data_Client( $oauth ); $stats = $ga->get_property_sessions_summary( $settings, $property_id, $start_date, $end_date ); if ( is_wp_error( $stats ) ) { $status = 'error'; $messages[] = sprintf( __( 'Analytics: %s', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $stats->get_error_message() ); } else { $sessions = isset( $stats['sessions'] ) ? absint( $stats['sessions'] ) : 0; $messages[] = sprintf( __( 'Analytics: OK (sessies laatste %1$d dagen: ~%2$d).', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $range_days, $sessions ); } } else { $messages[] = __( 'Analytics: overgeslagen (GA4 property ID niet ingevuld).', GROQ_AI_PRODUCT_TEXT_DOMAIN ); } } $url = add_query_arg( [ 'groq_ai_google_oauth' => $status, 'groq_ai_google_oauth_message' => implode( ' ', $messages ), ], $this->get_settings_page_url() ); wp_safe_redirect( $url ); exit; } public function render_google_gsc_site_url_field() { $settings = $this->plugin->get_settings(); $value = isset( $settings['google_gsc_site_url'] ) ? (string) $settings['google_gsc_site_url'] : ''; ?>
plugin->get_settings(); $value = isset( $settings['google_ga4_property_id'] ) ? (string) $settings['google_ga4_property_id'] : ''; ?>
plugin->get_settings(); $gsc = ! empty( $settings['google_enable_gsc'] ); $ga = ! empty( $settings['google_enable_ga'] ); ?> 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 ) { $url = add_query_arg( [ 'groq_ai_google_oauth' => 'error', 'groq_ai_google_oauth_message' => __( 'Vul eerst Google Client ID en Client secret in.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ], $this->get_settings_page_url() ); wp_safe_redirect( $url ); exit; } $state = wp_generate_password( 32, false, false ); set_transient( $this->get_google_oauth_state_key(), $state, 10 * MINUTE_IN_SECONDS ); $scope = implode( ' ', $this->get_google_oauth_scopes() ); $redirect_uri = $this->get_google_oauth_redirect_uri(); $auth_url = add_query_arg( [ 'client_id' => $client_id, 'redirect_uri' => $redirect_uri, 'response_type' => 'code', 'access_type' => 'offline', 'prompt' => 'consent', 'include_granted_scopes' => 'true', 'scope' => $scope, 'state' => $state, ], 'https://accounts.google.com/o/oauth2/v2/auth' ); $auth_url = esc_url_raw( $auth_url ); $parsed = wp_parse_url( $auth_url ); $host = isset( $parsed['host'] ) ? strtolower( (string) $parsed['host'] ) : ''; if ( 'accounts.google.com' !== $host ) { $url = add_query_arg( [ 'groq_ai_google_oauth' => 'error', 'groq_ai_google_oauth_message' => __( 'OAuth URL ongeldig. Controleer plugin instellingen.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ], $this->get_settings_page_url() ); wp_safe_redirect( $url ); exit; } // Let op: wp_safe_redirect staat standaard geen externe hosts toe en valt dan terug naar /wp-admin. wp_redirect( $auth_url ); exit; } public function handle_google_oauth_callback() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Geen toestemming.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) ); } $expected_state = get_transient( $this->get_google_oauth_state_key() ); delete_transient( $this->get_google_oauth_state_key() ); $state = isset( $_GET['state'] ) ? sanitize_text_field( wp_unslash( $_GET['state'] ) ) : ''; $code = isset( $_GET['code'] ) ? sanitize_text_field( wp_unslash( $_GET['code'] ) ) : ''; $error = isset( $_GET['error'] ) ? sanitize_text_field( wp_unslash( $_GET['error'] ) ) : ''; if ( '' !== $error ) { $url = add_query_arg( [ 'groq_ai_google_oauth' => 'error', 'groq_ai_google_oauth_message' => sprintf( __( 'Google OAuth error: %s', GROQ_AI_PRODUCT_TEXT_DOMAIN ), $error ), ], $this->get_settings_page_url() ); wp_safe_redirect( $url ); exit; } if ( empty( $expected_state ) || '' === $state || $state !== $expected_state ) { $url = add_query_arg( [ 'groq_ai_google_oauth' => 'error', 'groq_ai_google_oauth_message' => __( 'Ongeldige OAuth state. Probeer opnieuw te verbinden.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ], $this->get_settings_page_url() ); wp_safe_redirect( $url ); exit; } if ( '' === $code ) { $url = add_query_arg( [ 'groq_ai_google_oauth' => 'error', 'groq_ai_google_oauth_message' => __( 'Geen OAuth code ontvangen.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ], $this->get_settings_page_url() ); wp_safe_redirect( $url ); exit; } $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'] ) : ''; $redirect_uri = $this->get_google_oauth_redirect_uri(); if ( '' === $client_id || '' === $client_secret ) { $url = add_query_arg( [ 'groq_ai_google_oauth' => 'error', 'groq_ai_google_oauth_message' => __( 'Client ID/secret ontbreken. Sla eerst de instellingen op.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ], $this->get_settings_page_url() ); wp_safe_redirect( $url ); exit; } $token_response = wp_remote_post( 'https://oauth2.googleapis.com/token', [ 'timeout' => 20, 'headers' => [ 'Content-Type' => 'application/x-www-form-urlencoded', ], 'body' => [ 'code' => $code, 'client_id' => $client_id, 'client_secret' => $client_secret, 'redirect_uri' => $redirect_uri, 'grant_type' => 'authorization_code', ], ] ); if ( is_wp_error( $token_response ) ) { $url = add_query_arg( [ 'groq_ai_google_oauth' => 'error', 'groq_ai_google_oauth_message' => $token_response->get_error_message(), ], $this->get_settings_page_url() ); wp_safe_redirect( $url ); exit; } $status_code = wp_remote_retrieve_response_code( $token_response ); $body = wp_remote_retrieve_body( $token_response ); $data = json_decode( (string) $body, true ); if ( 200 !== $status_code || ! is_array( $data ) ) { $url = add_query_arg( [ 'groq_ai_google_oauth' => 'error', 'groq_ai_google_oauth_message' => __( 'Token exchange mislukt.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ], $this->get_settings_page_url() ); wp_safe_redirect( $url ); exit; } $access_token = isset( $data['access_token'] ) ? sanitize_text_field( (string) $data['access_token'] ) : ''; $refresh_token = isset( $data['refresh_token'] ) ? sanitize_text_field( (string) $data['refresh_token'] ) : ''; if ( '' === $refresh_token ) { $refresh_token = isset( $settings['google_oauth_refresh_token'] ) ? sanitize_text_field( (string) $settings['google_oauth_refresh_token'] ) : ''; } $connected_email = ''; if ( '' !== $access_token ) { $userinfo_response = wp_remote_get( 'https://openidconnect.googleapis.com/v1/userinfo', [ 'timeout' => 20, 'headers' => [ 'Authorization' => 'Bearer ' . $access_token, ], ] ); if ( ! is_wp_error( $userinfo_response ) && 200 === wp_remote_retrieve_response_code( $userinfo_response ) ) { $userinfo_body = wp_remote_retrieve_body( $userinfo_response ); $userinfo_data = json_decode( (string) $userinfo_body, true ); if ( is_array( $userinfo_data ) && ! empty( $userinfo_data['email'] ) ) { $connected_email = sanitize_email( (string) $userinfo_data['email'] ); } } } $options = get_option( $this->plugin->get_option_key(), [] ); if ( ! is_array( $options ) ) { $options = []; } $options['google_oauth_refresh_token'] = $refresh_token; $options['google_oauth_connected_email'] = $connected_email; $options['google_oauth_connected_at'] = time(); update_option( $this->plugin->get_option_key(), $options ); $url = add_query_arg( [ 'groq_ai_google_oauth' => 'success', 'groq_ai_google_oauth_message' => __( 'Google succesvol verbonden.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ], $this->get_settings_page_url() ); wp_safe_redirect( $url ); exit; } public function handle_google_oauth_disconnect() { if ( ! current_user_can( 'manage_options' ) ) { wp_die( esc_html__( 'Geen toestemming.', GROQ_AI_PRODUCT_TEXT_DOMAIN ) ); } check_admin_referer( 'groq_ai_google_oauth_disconnect' ); $options = get_option( $this->plugin->get_option_key(), [] ); if ( ! is_array( $options ) ) { $options = []; } $options['google_oauth_refresh_token'] = ''; $options['google_oauth_connected_email'] = ''; $options['google_oauth_connected_at'] = 0; update_option( $this->plugin->get_option_key(), $options ); $url = add_query_arg( [ 'groq_ai_google_oauth' => 'success', 'groq_ai_google_oauth_message' => __( 'Google koppeling verwijderd.', GROQ_AI_PRODUCT_TEXT_DOMAIN ), ], $this->get_settings_page_url() ); wp_safe_redirect( $url ); exit; } public function render_modules_page() { if ( ! current_user_can( 'manage_options' ) ) { return; } ?>
get_label() ) ); ?>
plugin->get_settings(); $value = isset( $settings['term_bottom_description_meta_key'] ) ? (string) $settings['term_bottom_description_meta_key'] : ''; ?>
plugin->get_settings(); $values = isset( $settings['context_fields'] ) ? $settings['context_fields'] : $this->plugin->get_default_context_fields(); $definitions = $this->plugin->get_context_field_definitions(); ?>
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(); ?>
/>
/>
/>