'', 'bound_property_label' => '', 'mode' => 'manual', ) ); }, 20 ); } /** * @return string */ public static function get_api_url() { if ( defined( 'AIVISY_SYNC_API_URL' ) && is_string( AIVISY_SYNC_API_URL ) && '' !== trim( AIVISY_SYNC_API_URL ) ) { return trim( AIVISY_SYNC_API_URL ); } if ( defined( 'AIVISY_APP_URL' ) && is_string( AIVISY_APP_URL ) && '' !== trim( AIVISY_APP_URL ) ) { return rtrim( trim( AIVISY_APP_URL ), '/' ) . '/wordpress_llms_sync_api.php'; } return (string) apply_filters( 'aivisy_sync_api_url', '' ); } /** * @param string|null $content Prior result. * @param array $settings Plugin settings. * @return string|\WP_Error|null */ public static function filter_sync( $content, $settings ) { if ( null !== $content && '' !== $content ) { return $content; } if ( empty( $settings['connected'] ) || empty( $settings['connection_token'] ) ) { return null; } if ( empty( $settings['bound_property_id'] ) ) { return new \WP_Error( 'aivisy_need_property', __( 'Select a GA4 property for this site first.', 'ai-view-sync' ) ); } $url = self::get_api_url(); if ( '' === $url ) { return null; } $args = array( 'timeout' => 45, 'redirection' => 2, 'sslverify' => true, 'headers' => array( 'Accept' => 'text/plain', ), ); $endpoint = add_query_arg( array( 'token' => (string) $settings['connection_token'], 'site_url' => home_url( '/' ), 'property_id' => isset( $settings['bound_property_id'] ) ? (string) $settings['bound_property_id'] : '', ), $url ); /** * HTTP args for AI View llms sync GET. * * @param array $args wp_remote_get args. * @param string $endpoint Full URL. * @param array $settings Settings. */ $args = apply_filters( 'aivisy_sync_remote_args', $args, $endpoint, $settings ); $response = wp_remote_get( $endpoint, $args ); if ( is_wp_error( $response ) ) { return $response; } $code = wp_remote_retrieve_response_code( $response ); $body = wp_remote_retrieve_body( $response ); if ( $code >= 400 ) { $msg = trim( (string) $body ); if ( '' === $msg ) { $msg = 'HTTP ' . (string) $code; } // Site vs GA4 property mismatch: clear the bind so the user can pick the right property in WordPress. // Defer option writes to shutdown so we never update settings mid-filter (avoids rare re-entrancy fatals). if ( 403 === (int) $code && strpos( $msg, 'does not match the GA4 property' ) !== false ) { $msg .= ' ' . __( 'Choose the correct GA4 property for this site below, then use Sync again.', 'ai-view-sync' ); self::schedule_clear_bound_property_after_request(); } return new \WP_Error( 'aivisy_sync_http', $msg, array( 'status' => $code ) ); } return $body; } }