ai_optimizer_helper = $ai_optimizer_helper; } // phpcs:disable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber -- PHPCS doesn't take into account exceptions thrown in called methods. /** * Action used to generate improved copy through AI, that scores better on our content analysis' assessments. * * @param WP_User $user The WP user. * @param string $assessment The assessment to improve. * @param string $language The language of the post. * @param string $prompt_content The excerpt taken from the post. * @param string $focus_keyphrase The focus keyphrase associated to the post. * @param string $synonyms Synonyms for the focus keyphrase. * @param bool $retry_on_unauthorized Whether to retry when unauthorized (mechanism to retry once). * * @return string The AI-generated content. * * @throws Bad_Request_Exception Bad_Request_Exception. * @throws Forbidden_Exception Forbidden_Exception. * @throws Internal_Server_Error_Exception Internal_Server_Error_Exception. * @throws Not_Found_Exception Not_Found_Exception. * @throws Payment_Required_Exception Payment_Required_Exception. * @throws Request_Timeout_Exception Request_Timeout_Exception. * @throws Service_Unavailable_Exception Service_Unavailable_Exception. * @throws Too_Many_Requests_Exception Too_Many_Requests_Exception. * @throws Unauthorized_Exception Unauthorized_Exception. * @throws RuntimeException Unable to retrieve the access token. */ public function optimize( WP_User $user, string $assessment, string $language, string $prompt_content, string $focus_keyphrase, string $synonyms, bool $retry_on_unauthorized = true ): string { $token = $this->get_or_request_access_token( $user ); $subject = [ 'language' => $language, 'content' => $prompt_content, ]; // We are not sending the synonyms for now, as these are not used in the current prompts. if ( $focus_keyphrase !== '' ) { $subject['focus_keyphrase'] = $focus_keyphrase; } $request_body = [ 'service' => 'openai', 'user_id' => (string) $user->ID, 'subject' => $subject, ]; $request_headers = [ 'Authorization' => "Bearer $token", ]; try { $response = $this->ai_generator_helper->request( "/fix/assessments/$assessment", $request_body, $request_headers ); } catch ( Unauthorized_Exception $exception ) { // Delete the stored JWT tokens, as they appear to be no longer valid. $this->user_helper->delete_meta( $user->ID, '_yoast_wpseo_ai_generator_access_jwt' ); $this->user_helper->delete_meta( $user->ID, '_yoast_wpseo_ai_generator_refresh_jwt' ); if ( ! $retry_on_unauthorized ) { throw $exception; } // Try again once more by fetching a new set of tokens and trying the suggestions endpoint again. return $this->optimize( $user, $assessment, $language, $prompt_content, $focus_keyphrase, $synonyms, false ); } catch ( Forbidden_Exception $exception ) { // Follow the API in the consent being revoked (Use case: user sent an e-mail to revoke?). // phpcs:disable WordPress.Security.EscapeOutput.ExceptionNotEscaped -- false positive. throw $this->handle_consent_revoked( $user->ID, $exception->getCode() ); // phpcs:enable WordPress.Security.EscapeOutput.ExceptionNotEscaped } return $this->ai_optimizer_helper->build_optimize_response( $assessment, $prompt_content, $response ); } // phpcs:enable Squiz.Commenting.FunctionCommentThrowTag.WrongNumber }