PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.2.6
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.2.6
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
← All changes | includes/Core/WriteWithAI.php +152 -144 4.4.14.2.6 View file →
@@ -1,171 +1,172 @@
1 1 <?php
2 2
3 - namespace WPDeveloper\BetterDocs\Core;
3 +namespace WPDeveloper\BetterDocs\Core;
4 4
5 - use WPDeveloper\BetterDocs\Utils\Base;
6 - use WPDeveloper\BetterDocs\Core\Settings;
7 - use WPDeveloper\BetterDocs\Core\PostType;
5 +use WPDeveloper\BetterDocs\Utils\Base;
6 +use WPDeveloper\BetterDocs\Core\Settings;
7 +use WPDeveloper\BetterDocs\Core\PostType;
8 8
9 - use WPDeveloper\BetterDocs\Utils\Helper;
9 +use WPDeveloper\BetterDocs\Utils\Helper;
10 10
11 - class WriteWithAI extends Base {
11 +class WriteWithAI extends Base {
12 12
13 - public $settings;
13 + public $settings;
14 14
15 - public function __construct( Settings $settings ) {
16 - $this->settings = $settings;
15 + public function __construct( Settings $settings ) {
16 + $this->settings = $settings;
17 + // Get the post ID from the URL
18 + $post_id = isset($_GET['post']) ? intval($_GET['post']) : 0; // phpcs:ignore
17 19
18 - if ( ! empty( $this->isEnabledWriteWithAI() ) ) {
19 - add_action( 'current_screen', array( $this, 'maybe_register_ai_autowrite_button' ) );
20 - }
21 - add_action( 'wp_ajax_generate_openai_content', array( $this, 'generate_openai_content_callback' ) );
22 - }
20 + if (!empty($_GET['post_type'])) { // phpcs:ignore
21 + $post_type = $_GET['post_type']; // phpcs:ignore
22 + } elseif ( $post_id > 0 ) {
23 + $post_type = get_post_type( $post_id );
24 + } else {
25 + $post_type = '';
26 + }
23 27
24 - public function maybe_register_ai_autowrite_button() {
25 - if ( ! current_user_can( 'edit_posts' ) ) {
26 - return;
27 - }
28 + if ( ! empty( $this->isEnabledWriteWithAI() ) && $post_type == 'docs' ) {
29 + add_action( 'admin_footer', [ $this, 'ai_autowrite_button' ] );
30 + }
31 + add_action( 'wp_ajax_generate_openai_content', [ $this, 'generate_openai_content_callback' ] );
28 32
29 - $screen = get_current_screen();
30 - if ( $screen && 'docs' === $screen->post_type && 'post' === $screen->base ) {
31 - add_action( 'admin_footer', array( $this, 'ai_autowrite_button' ) );
32 - }
33 - }
33 + }
34 34
35 - public function isEnabledWriteWithAI() {
36 - $isEnableAutoWrite = $this->settings->get( 'enable_write_with_ai', true );
37 - return $isEnableAutoWrite;
38 - }
35 + public function isEnabledWriteWithAI() {
36 + $isEnableAutoWrite = $this->settings->get( 'enable_write_with_ai', true );
37 + return $isEnableAutoWrite;
38 + }
39 39
40 - public function isValidAPIKey( $apiKey ) {
41 - if ( empty( $apiKey ) ) {
42 - $api_response[ 'valid' ] = false;
43 - $api_response[ 'message' ] = 'Please Insert your <a href="/admin.php?page=betterdocs-settings">OpenAI API Key</a> to use this Write with AI feature.';
40 + public function isValidAPIKey( $apiKey ) {
41 + if ( empty( $apiKey ) ) {
42 + $api_response['valid'] = false;
43 + $api_response['message'] = 'Please Insert your <a href="/admin.php?page=betterdocs-settings">OpenAI API Key</a> to use this Write with AI feature.';
44 44
45 - return $api_response;
46 - }
45 + return $api_response;
46 + }
47 47
48 - $ch = curl_init( 'https://api.openai.com/v1/engines' ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_init
49 - curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt
50 - curl_setopt(
51 - $ch,
52 - CURLOPT_HTTPHEADER,
53 - array( //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt
54 - 'Content-Type: application/json',
55 - 'Authorization: Bearer ' . $apiKey
56 - )
57 - );
48 + $ch = curl_init( 'https://api.openai.com/v1/engines' ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_init
49 + curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt
50 + curl_setopt(
51 + $ch,
52 + CURLOPT_HTTPHEADER,
53 + [ //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_setopt
54 + 'Content-Type: application/json',
55 + 'Authorization: Bearer ' . $apiKey,
56 + ]
57 + );
58 58
59 - $api_response = array();
59 + $api_response = [];
60 60
61 - $response = curl_exec( $ch ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_exec
62 - $httpCode = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_getinfo
61 + $response = curl_exec( $ch ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_exec
62 + $httpCode = curl_getinfo( $ch, CURLINFO_HTTP_CODE ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_getinfo
63 63
64 - curl_close( $ch ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_close
64 + curl_close( $ch ); //phpcs:ignore WordPress.WP.AlternativeFunctions.curl_curl_close
65 65
66 - if ( 200 == $httpCode ) {
67 - $api_response[ 'valid' ] = true;
68 - $api_response[ 'message' ] = 'Valid API Key';
69 - } else {
70 - $responseData = json_decode( $response, true );
71 - // Access the message data (replace 'data' with the actual key used in the response)
72 - $messageData = $responseData[ 'error' ] ? $responseData[ 'error' ] : '';
73 - $api_response[ 'valid' ] = false;
74 - $api_response[ 'message' ] = $messageData[ 'message' ] ? $messageData[ 'message' ] : 'Invalid API Key';
75 - }
66 + if ( $httpCode == 200 ) {
67 + $api_response['valid'] = true;
68 + $api_response['message'] = 'Valid API Key';
69 + } else {
70 + $responseData = json_decode( $response, true );
71 + // Access the message data (replace 'data' with the actual key used in the response)
72 + $messageData = $responseData['error'] ? $responseData['error'] : '';
73 + $api_response['valid'] = false;
74 + $api_response['message'] = $messageData['message'] ? $messageData['message'] : 'Invalid API Key';
75 + }
76 76
77 - // print_r($response);
77 + // print_r($response);
78 78
79 - return $api_response;
80 - }
79 + return $api_response;
80 + }
81 81
82 - public function get_api_key() {
83 - $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
84 - return $api_key;
85 - }
82 + public function get_api_key() {
83 + $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
84 + return $api_key;
85 + }
86 86
87 - public function generate_openai_response( $prompt, $keywords ) {
88 - try {
89 - $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
90 - $max_tokens = $this->settings->get( 'ai_autowrite_max_token', 1500 );
91 - $model = $this->settings->get( 'write_with_ai_model', 'gpt-4o-mini' );
92 87
93 - $api_endpoint = 'https://api.openai.com/v1/chat/completions'; // Update the endpoint based on OpenAI API version
88 + public function generate_openai_response( $prompt, $keywords ) {
89 + try {
90 + $api_key = $this->settings->get( 'ai_autowrite_api_key', '' );
91 + $max_tokens = $this->settings->get( 'ai_autowrite_max_token', 1500 );
92 + $model = $this->settings->get( 'write_with_ai_model', 'gpt-4o-mini' );
94 93
95 - $request_options = array(
96 - 'headers' => array(
97 - 'Content-Type' => 'application/json',
98 - 'Authorization' => 'Bearer ' . $api_key
99 - ),
100 - 'body' => json_encode(
101 - array(
102 - 'model' => $model,
103 - 'messages' => array(
104 - array(
105 - 'role' => 'system',
106 - 'content' => 'You are a Senior Technical Writer specializing in comprehensive, high-quality documentation. Your goal is to write documentation that scores 100/100 on clarity, completeness, and structure.'
107 - ),
108 - array(
109 - 'role' => 'user',
110 - 'content' => $prompt
111 - )
112 - ),
113 - 'max_tokens' => $max_tokens
114 - )
115 - ),
116 - 'timeout' => 50
117 - );
94 + $api_endpoint = 'https://api.openai.com/v1/chat/completions'; // Update the endpoint based on OpenAI API version
118 95
119 - $response = wp_remote_post( $api_endpoint, $request_options );
96 + $request_options = array(
97 + 'headers' => array(
98 + 'Content-Type' => 'application/json',
99 + 'Authorization' => 'Bearer ' . $api_key,
100 + ),
101 + 'body' => json_encode(
102 + array( //phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode
103 + 'model' => $model, // Add the model parameter here
104 + 'messages' => array(
105 + array(
106 + 'role' => 'system',
107 + 'content' => 'You are a helpful assistant who writes documentation for users.'
108 + ),
109 + array(
110 + 'role' => 'user',
111 + 'content' => $prompt
112 + ),
113 + ),
114 + 'max_tokens' => $max_tokens,
120 115
121 - if ( is_wp_error( $response ) ) {
122 - return 'Error: ' . $response->get_error_message();
123 - } else {
124 - $body = wp_remote_retrieve_body( $response );
116 + )
117 + ),
118 + 'timeout' => 50,
119 + );
125 120
126 - $data = json_decode( $body, true );
121 + $response = wp_remote_post( $api_endpoint, $request_options );
127 122
128 - if ( ! empty( $data[ 'error' ] ) ) {
129 - return $data[ 'error' ][ 'message' ];
130 - }
123 + if ( is_wp_error( $response ) ) {
124 + return 'Error: ' . $response->get_error_message();
125 + } else {
126 + $body = wp_remote_retrieve_body( $response );
131 127
132 - return $data[ 'choices' ][ 0 ][ 'message' ][ 'content' ]; // Update this line to get the assistant's message
133 - }
134 - } catch ( Exception $error ) {
135 - return 'Error: ' . $error->getMessage();
136 - }
137 - }
128 + $data = json_decode( $body, true );
138 129
139 - public function generate_openai_content_callback() {
140 - if ( ! current_user_can( 'edit_posts' ) ) {
141 - wp_send_json_error( 'Unauthorized' );
142 - wp_die();
143 - }
130 + if ( ! empty( $data['error'] ) ) {
131 + return $data['error']['message'];
132 + }
144 133
145 - // Verify the nonce
146 - if ( ! isset( $_POST[ 'ai_nonce' ] ) || ! wp_verify_nonce( $_POST[ 'ai_nonce' ], 'generate_openai_content_nonce' ) ) { //phpcs:ignore
147 - wp_send_json_error( 'Invalid nonce' );
148 - wp_die();
149 - }
134 + return $data['choices'][0]['message']['content']; // Update this line to get the assistant's message
135 + }
136 + } catch ( Exception $error ) {
137 + return 'Error: ' . $error->getMessage();
138 + }
139 + }
150 140
151 - $prompt = sanitize_text_field( $_POST[ 'prompt' ] ); //phpcs:ignore
152 - // $num_of_sections = sanitize_text_field($_POST['numOfSections']);
153 - // $num_of_paragraphs = sanitize_text_field($_POST['numOfParagraphs']);
154 - $keywords = sanitize_text_field( $_POST[ 'keywords' ] ); //phpcs:ignore
155 141
156 - $ai_instance = new WriteWithAI( $this->settings );
157 142
158 - $generated_content = $ai_instance->generate_openai_response( $prompt, $keywords );
143 + public function generate_openai_content_callback() {
144 + // Verify the nonce
145 + if (!isset($_POST['ai_nonce']) || !wp_verify_nonce($_POST['ai_nonce'], 'generate_openai_content_nonce')) { //phpcs:ignore
146 + wp_send_json_error( 'Invalid nonce' );
147 + wp_die();
148 + }
159 149
160 - // Send the generated content as the AJAX response
161 - wp_send_json_success( $generated_content );
162 - wp_die();
163 - }
150 + $prompt = sanitize_text_field($_POST['prompt']); //phpcs:ignore
151 + // $num_of_sections = sanitize_text_field($_POST['numOfSections']);
152 + // $num_of_paragraphs = sanitize_text_field($_POST['numOfParagraphs']);
153 + $keywords = sanitize_text_field($_POST['keywords']); //phpcs:ignore
164 154
165 - public function ai_autowrite_button() {
155 + $ai_instance = new WriteWithAI( $this->settings );
166 156
167 - ?>
157 + $generated_content = $ai_instance->generate_openai_response( $prompt, $keywords );
158 +
159 + // Send the generated content as the AJAX response
160 + wp_send_json_success( $generated_content );
161 + wp_die();
162 + }
163 +
164 +
165 +
166 + public function ai_autowrite_button() {
167 +
168 + ?>
168 169 <script>
169 170 var docsTitle;
170 171
171 172 function responseMessage(message) {
@@ -231,8 +232,14 @@
231 232 setTimeout(() => {
232 233 insertContentToEditor(title, response.data, isOverwrite, keywords);
233 234 docGenerateBtnTxt.innerHTML = reGenerateDocLabel;
234 235 jQuery('.generate-btn').removeAttr('disabled');
236 +
237 + // console.log(jQuery('.betterdocs-ai-autowrite-form-container').data('new-doc-page'));
238 +
239 + // if(jQuery('.betterdocs-ai-autowrite-form-container')?.data('new-doc-page')) {
240 + // docGenerateBtnTxt.innerHTML = reGenerateDocLabel;
241 + // }
235 242 }, 2000);
236 243 } else {
237 244 // alert(response.data.message);
238 245 jQuery('#betterdocs-ai-error-message').parent().removeClass('hidden');
@@ -317,8 +324,9 @@
317 324 var match = htmlString.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
318 325
319 326 // Check if match is null before accessing match[1]
320 327 if (match) {
328 + console.log(match[1].replace(/<p>\s+/g, '<p>'));
321 329 return match[1].replace(/<p>\s+/g, '<p>');
322 330 } else {
323 331 return '';
324 332 }
@@ -335,9 +343,9 @@
335 343
336 344 htmlContent = getBodyContent(htmlContent);
337 345 htmlContent = removeFirstHeading(htmlContent);
338 346 htmlContent = wrapwithHeighlight(htmlContent, keywords);
339 - const isPostContent = `<?php echo isset( $_GET[ 'post' ] ) ? esc_html( get_the_content( $_GET[ 'post' ] ) ) : ''; // phpcs:ignore ?>`;
347 + const isPostContent = `<?php echo isset($_GET['post']) ? esc_html(get_the_content($_GET['post'])) : ''; // phpcs:ignore ?>`;
340 348
341 349 const blocks = wp.blocks.rawHandler({
342 350 HTML: htmlContent
343 351 });
@@ -409,14 +417,14 @@
409 417
410 418
411 419 function writeWithAIForm() {
412 420
413 - let title = `<?php echo isset( $_GET[ 'post' ] ) ? esc_html( get_the_title( $_GET[ 'post' ] ) ) : ''; // phpcs:ignore ?>`;
421 + let title = `<?php echo isset($_GET['post']) ? esc_html(get_the_title($_GET['post'])) : ''; // phpcs:ignore ?>`;
414 422 if (docsTitle) {
415 423 title = docsTitle;
416 424 }
417 425
418 - const promtTitle = `<?php echo isset( $_GET[ 'post' ] ) ? esc_html( get_the_title( $_GET[ 'post' ] ) ) : '{Documentation Title}'; // phpcs:ignore ?>`;
426 + const promtTitle = `<?php echo isset($_GET['post']) ? esc_html(get_the_title($_GET['post'])) : '{Documentation Title}'; // phpcs:ignore ?>`;
419 427 const titlePlaceholder = "<?php echo esc_attr__( 'Enter a descriptive title for your documentation.', 'betterdocs' ); ?>";
420 428 const keywords = "<?php echo esc_attr( '{Documentation Keywords}' ); ?>";
421 429 const keywordsPlaceholder = "<?php echo esc_attr__( 'Add keywords to generate precise & relevant documentation (comma-separated).', 'betterdocs' ); ?>";
422 430 const language = "<?php echo esc_attr( 'English' ); ?>";
@@ -431,18 +439,18 @@
431 439 const checkboxLabel = "<?php echo esc_html__( 'Overwrite your existing Doc:', 'betterdocs' ); ?>";
432 440 const nonce = "<?php echo esc_attr( wp_create_nonce( 'generate_openai_content_nonce' ) ); ?>";
433 441
434 442 <?php
435 - $is_valid = $this->get_api_key();
436 - $disable_field = 'disabled-input-field';
437 - if ( $this->get_api_key() ) {
438 - $disable_field = '';
439 - }
440 - ?>
443 + $is_valid = $this->get_api_key();
444 + $disable_field = 'disabled-input-field';
445 + if ( $this->get_api_key() ) {
446 + $disable_field = '';
447 + }
448 + ?>
441 449
442 450 let hiddenClass = 'hidden';
443 451 let newDocPageAtt = 'data-new-doc-page="true"';
444 - const isPostContent = `<?php echo isset( $_GET[ 'post' ] ) ? esc_html( get_the_content( $_GET[ 'post' ] ) ) : ''; // phpcs:ignore ?>`;
452 + const isPostContent = `<?php echo isset($_GET['post']) ? esc_html(get_the_content($_GET['post'])) : ''; // phpcs:ignore ?>`;
445 453
446 454 if (isPostContent !== '') {
447 455 hiddenClass = '';
448 456 newDocPageAtt = '';
@@ -491,14 +499,14 @@
491 499 <div class="autowrite-subheadding">
492 500 <p><?php echo esc_html__( 'Generate documentation effortlessly with BetterDocs AI. Simply input your doc title, keywords, prompt and let the system automatically generate comprehensive documentation tailored to your needs.', 'betterdocs' ); ?></p>
493 501 </div>
494 502
495 - <?php if ( empty( $this->get_api_key() ) ): ?>
503 + <?php if ( empty( $this->get_api_key() ) ) : ?>
496 504 <div id="betterdocs-ai-message">
497 505 <div class="warning-message">
498 506 <span class="dashicons dashicons-warning"></span>
499 507 <div>
500 - <?php echo wp_kses_post( 'Please Insert your <a target="_blank" href="' . esc_url( admin_url( 'admin.php?page=betterdocs-settings&tab=tab-betterdocs-ai' ) ) . '">OpenAI API Key</a> to use this Write with AI feature.', 'betterdocs' ); ?>
508 + <?php echo wp_kses_post( 'Please Insert your <a target="_blank" href="' . esc_url( admin_url( 'admin.php?page=betterdocs-settings&tab=tab-ai-autowrite' ) ) . '">OpenAI API Key</a> to use this Write with AI feature.', 'betterdocs' ); ?>
501 509 </div>
502 510 </div>
503 511
504 512 </div>
@@ -1110,6 +1118,6 @@
1110 1118
1111 1119 }
1112 1120 </style>
1113 1121 <?php
1114 - }
1115 - }
1122 + }
1123 +}