PluginProbe
Post Grid Gutenberg Blocks – PostX / 5.1.1
Post Grid Gutenberg Blocks – PostX v5.1.1
5.1.1 5.1.0 5.0.41 5.0.39 5.0.38 5.0.37 5.0.36 5.0.35 5.0.34 5.0.33 5.0.32 5.0.31 5.0.30 5.0.29 5.0.28 5.0.27 5.0.26 5.0.25 5.0.23 5.0.24 5.0.22 5.0.21 5.0.20 5.0.19 5.0.18 All 240 releases
← All changes | addons/chatgpt/init.php +108 -3 5.0.26 → 5.1.1 View file →
@@ -3,13 +3,118 @@
3 3
4 4 add_action( 'init', 'ultp_chatgpt_init' );
5 5 function ultp_chatgpt_init() {
6 6 if ( ultimate_post()->get_setting( 'ultp_chatgpt' ) == 'true' ) {
7 - add_filter( 'ultp_settings', 'get_chatgpt_settings', 10, 1 );
7 + add_filter( 'ultp_settings', 'ultp_get_chatgpt_settings', 10, 1 );
8 + add_action( 'rest_api_init', 'ultp_chatgpt_register_route' );
8 9 }
9 10 }
10 11
11 -function get_chatgpt_settings( $config ) {
12 +/**
13 + * Register the route the editor uses to ask OpenAI.
14 + *
15 + * The OpenAI key stays on the server: the editor sends only the prompt, and
16 + * this route adds the key and the saved model settings.
17 + */
18 +function ultp_chatgpt_register_route() {
19 + register_rest_route(
20 + 'ultp/v2',
21 + '/chatgpt/',
22 + array(
23 + 'methods' => 'POST',
24 + 'callback' => 'ultp_chatgpt_request',
25 + 'permission_callback' => function () {
26 + return current_user_can( 'edit_posts' );
27 + },
28 + 'args' => array(
29 + 'prompt' => array(
30 + 'type' => 'string',
31 + 'required' => true,
32 + ),
33 + ),
34 + )
35 + );
36 +}
37 +
38 +/**
39 + * Send a prompt to OpenAI with the saved key and settings.
40 + *
41 + * Returns OpenAI's `choices` on success, or `error.code` (plus the message for
42 + * a missing model) on failure, which is the shape the editor already reads.
43 + * OpenAI's other error messages are not passed on, as some quote part of the key.
44 + *
45 + * @param WP_REST_Request $request Request.
46 + * @return WP_REST_Response|WP_Error
47 + */
48 +function ultp_chatgpt_request( $request ) {
49 + $api_key = ultimate_post()->get_setting( 'chatgpt_secret_key' );
50 + if ( empty( $api_key ) ) {
51 + return rest_ensure_response( array( 'error' => array( 'code' => 'invalid_api_key' ) ) );
52 + }
53 +
54 + $prompt = trim( wp_check_invalid_utf8( (string) $request->get_param( 'prompt' ) ) );
55 + if ( '' === $prompt ) {
56 + return new WP_Error( 'ultp_chatgpt_empty_prompt', __( 'The prompt is empty.', 'ultimate-post' ), array( 'status' => 400 ) );
57 + }
58 + $prompt = mb_substr( $prompt, 0, 20000 );
59 +
60 + $model = ultimate_post()->get_setting( 'chatgpt_model' );
61 + if ( ! in_array( $model, array( 'gpt-3.5-turbo', 'gpt-4', 'text-davinci-002', 'text-davinci-003' ), true ) ) {
62 + $model = 'gpt-3.5-turbo';
63 + }
64 + $timeout = absint( ultimate_post()->get_setting( 'chatgpt_response_time' ) );
65 + $timeout = $timeout ? min( max( $timeout, 5 ), 120 ) : 35;
66 +
67 + if ( 0 === strpos( $model, 'text-davinci' ) ) {
68 + $max_tokens = absint( ultimate_post()->get_setting( 'chatgpt_max_tokens' ) );
69 + $url = 'https://api.openai.com/v1/completions';
70 + $body = array(
71 + 'model' => $model,
72 + 'prompt' => $prompt,
73 + 'max_tokens' => $max_tokens ? min( $max_tokens, 4096 ) : 200,
74 + );
75 + } else {
76 + $url = 'https://api.openai.com/v1/chat/completions';
77 + $body = array(
78 + 'model' => $model,
79 + 'messages' => array(
80 + array(
81 + 'role' => 'user',
82 + 'content' => $prompt,
83 + ),
84 + ),
85 + );
86 + }
87 +
88 + $response = wp_safe_remote_post(
89 + $url,
90 + array(
91 + 'timeout' => $timeout,
92 + 'headers' => array(
93 + 'Content-Type' => 'application/json',
94 + 'Authorization' => 'Bearer ' . $api_key,
95 + ),
96 + 'body' => wp_json_encode( $body ),
97 + )
98 + );
99 + if ( is_wp_error( $response ) ) {
100 + return rest_ensure_response( array( 'error' => array( 'code' => 'request_failed' ) ) );
101 + }
102 +
103 + $data = json_decode( wp_remote_retrieve_body( $response ), true );
104 + if ( ! empty( $data['choices'] ) && is_array( $data['choices'] ) ) {
105 + return rest_ensure_response( array( 'choices' => $data['choices'] ) );
106 + }
107 +
108 + $code = isset( $data['error']['code'] ) ? sanitize_key( $data['error']['code'] ) : 'request_failed';
109 + $error = array( 'code' => $code );
110 + if ( 'model_not_found' === $code && isset( $data['error']['message'] ) ) {
111 + $error['message'] = sanitize_text_field( $data['error']['message'] );
112 + }
113 + return rest_ensure_response( array( 'error' => $error ) );
114 +}
115 +
116 +function ultp_get_chatgpt_settings( $config ) {
12 117 $arr = array(
13 118 'ultp_chatgpt' => array(
14 119 'label' => __( 'ChatGPT', 'ultimate-post' ),
15 120 'attr' => array(
@@ -20,9 +125,9 @@
20 125 'chatgpt_secret_key' => array(
21 126 'type' => 'text',
22 127 'label' => __( 'OpenAI API Secret Key', 'ultimate-post' ),
23 128 'desc' => __( 'For using ChatGPT addon, you have to add your OpenAI secret key.', 'ultimate-post' ),
24 - 'link' => __( 'https://platform.openai.com/account/api-keys' ),
129 + 'link' => 'https://platform.openai.com/account/api-keys',
25 130 'linkText' => __( 'Get key.', 'ultimate-post' ),
26 131 ),
27 132 'chatgpt_model' => array(
28 133 'type' => 'select',