PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.8.9
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.8.9
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
betterdocs / includes / REST / Settings.php

Settings.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 3.8.9, at includes/REST/Settings.php

405 lines 12.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPDeveloper\BetterDocs\REST;
4
5 use WP_Query;
6 use WP_REST_Request;
7 use WPDeveloper\BetterDocs\Admin\CSVExporter;
8 use WPDeveloper\BetterDocs\Admin\Importer\Parsers\CSV_Parser;
9 use WPDeveloper\BetterDocs\Admin\Importer\WPImport;
10 use WPDeveloper\BetterDocs\Admin\ReportEmail;
11 use WPDeveloper\BetterDocs\Admin\WPExporter;
12 use WPDeveloper\BetterDocs\Core\BaseAPI;
13 use WPDeveloper\BetterDocs\Dependencies\DI\DependencyException;
14 use WPDeveloper\BetterDocs\Dependencies\DI\NotFoundException;
15 use WPDeveloper\BetterDocsChatbot\Core\AIChatbot;
16
17 class Settings extends BaseAPI {
18
19 public function permission_check(): bool {
20 return current_user_can( 'edit_docs_settings' );
21 }
22
23 public function register() {
24 $this->get( 'settings', [ $this, 'get_settings' ] );
25 $this->post( 'dark-mode', [ $this, 'dark_mode' ] );
26 $this->post( 'settings', [ $this, 'save_settings' ] );
27 $this->post( 'plugin_insights', [ $this, 'plugin_insights' ] );
28 $this->post( 'create-sample-docs', [$this, 'sample_docs'] );
29 $this->post( 'reporting-test', [ $this, 'test_reporting' ] );
30 $this->post( 'export-docs', [ $this, 'export_docs' ] );
31 if(
32 get_option('betterdocs_chatbot_software__license_status') === 'valid' &&
33 get_option('betterdocs_pro_software__license_status') === 'valid'
34 ){
35 $this->post( 'save-aichatbot', [ $this, 'save_aichatbot' ] );
36 }
37 $this->post( 'export-settings', [ $this, 'export_settings' ] );
38 $this->post( 'import-docs', [ $this, 'import_docs' ] );
39 $this->post( 'import-settings', [ $this, 'import_settings' ] );
40 $this->post( 'parse-xml', [ $this, 'parse_xml' ] );
41 $this->post( 'parse-csv', [ $this, 'parse_csv' ] );
42 $this->post( 'migrate', [ $this, 'migrate_plugins' ] );
43 $this->post( 'helpscout-migration', [$this, 'helpscout_migration'] );
44 $this->post( 'dashboard-mode', [$this, 'dashboard_mode'] );
45 }
46
47 public function dashboard_mode( WP_REST_Request $request ) {
48 $mode = $request->get_param( 'dashboard_mode' );
49 return update_option( 'dashboard_mode', $mode );
50 }
51
52 public function dark_mode( WP_REST_Request $request ): bool {
53 $dark_mode = rest_sanitize_boolean( $request->get_param( 'mode' ) );
54
55 if ( betterdocs()->settings->save( 'dark_mode', $dark_mode ) ) {
56 return true;
57 }
58
59 return false;
60 }
61
62 public function sample_docs( WP_REST_Request $request ) {
63 $action = $request->get_param( 'action' );
64
65 if ( $action == 'create-dummy-data' ) {
66 $file = BETTERDOCS_ABSPATH . 'assets/admin/images/BetterDocs-sample-data.csv';
67 $args = [
68 'fetch_attachments' => true,
69 'action' => '',
70 'existing_slug' => '',
71 'file_type' => 'text/csv'
72 ];
73 $wp_import_object = new WPImport( $file, $args );
74 return $wp_import_object->run();
75 }
76 }
77
78 public function export_docs( WP_REST_Request $request ) {
79 $data = $request->get_params();
80 $args = [
81 'include_post_featured_image_as_attachment' => true,
82 'status' => 'publish',
83 'content' => $data['export_type'] == 'glossaries' ? 'glossaries' : 'docs',
84 'selected_docs' => $data['export_docs'],
85 'include_faq' => $data['enable_export_faq'],
86 ];
87
88 if ( $data['export_type'] == 'docs' && $data['export_docs'][0] != 'all' ) {
89 $args['post__in'] = $data['export_docs'];
90 }
91
92 if ( $data['export_type'] == 'doc_category' && $data['export_categories'][0] != 'all' ) {
93 $args['category_terms'] = $data['export_categories'];
94 }
95
96 if ( $data['export_type'] == 'knowledge_base' && $data['export_kbs'][0] != 'all' ) {
97 $args['kb_terms'] = $data['export_kbs'];
98 }
99
100 if ( $data['export_type'] == 'glossaries' && $data['export_glossaries'][0] != 'all' ) {
101 $args['glossary_terms'] = $data['export_glossaries'];
102 unset( $args['selected_docs'] );
103 }
104
105 if ( $data['file_type'] == 'xml' ) {
106 $exporter = new WPExporter( $args );
107 } elseif ( $data['file_type'] == 'csv' ) {
108 $exporter = new CSVExporter( $args );
109 }
110
111 /**
112 * @var WPExporter|CSVExporter $exporter
113 */
114
115 return $exporter->run();
116 }
117
118 public function save_aichatbot( WP_REST_Request $request ) {
119 $data = $request->get_params();
120
121 betterdocs()->settings->save( 'enable_ai_chatbot', $data['enable_ai_chatbot'] );
122
123 $api_status = AIChatbot::check_openai_quota($data['ai_chatbot_api_key']);
124
125 $api_status = json_decode($api_status, true); // Decode the JSON response
126
127 // Check if required data is empty
128 if ( empty( $data['ai_chatbot_api_key'] ) ||
129 empty( $data['ai_chatbot_embed_model'] ) ||
130 empty( $data['ai_chatbot_chat_model'] ) ) {
131 return [
132 'status' => 'error',
133 'message' => __('Required fields cannot be empty.', 'betterdocs'),
134 ];
135 }
136
137 if (isset($api_status['error'])) { // Check if the 'error' key exists in the response
138 $error_message = $api_status['error']['message'] ?? 'Unknown error';
139 return [
140 'status' => 'error',
141 'message' => __($error_message, 'betterdocs'),
142 ];
143 }
144
145
146 // Get previous values
147 $prev_api_key = betterdocs()->settings->get( 'ai_chatbot_api_key', '' );
148 $prev_embed_model = betterdocs()->settings->get( 'ai_chatbot_embed_model', '' );
149
150 // Save settings if all required fields are provided
151 betterdocs()->settings->save( 'ai_chatbot_api_key', $data['ai_chatbot_api_key'] );
152 betterdocs()->settings->save( 'ai_chatbot_embed_model', $data['ai_chatbot_embed_model'] );
153 betterdocs()->settings->save( 'ai_chatbot_chat_model', $data['ai_chatbot_chat_model'] );
154
155 // Execute if ai_chatbot_embed_model has changed
156 if ( $prev_embed_model !== $data['ai_chatbot_embed_model'] ) {
157 update_option( 'is_ai_chatbot_bg_complete', 'running' );
158 update_option( 'background_process_status', 1 );
159 AIChatbot::send_data();
160 }
161
162 $post_type = 'docs'; //betterdocs()->settings->get('ai_chatbot_allow_post_types', 'docs');
163 $docs_count = AIChatbot::get_docs_count( $post_type ); // Calculate the number of iterations needed
164 update_option( 'docs_count', $docs_count );
165
166
167 if($docs_count < 1){
168 update_option( 'background_process_status', 0 );
169 update_option( 'is_ai_chatbot_bg_complete', 'complete' );
170 update_option( 'show_ai_chatbot_process_notices', 0 );
171 }
172
173 // Execute if ai_chatbot_api_key has changed
174 if ( $prev_api_key !== $data['ai_chatbot_api_key'] ) {
175 $openai_api_key = $data['ai_chatbot_api_key'];
176 AIChatbot::encrypted_api_key( $openai_api_key, '0kXsYZmsHgvIB85miXWlq3nigYYD4PktOSVvOs3vlbA=' );
177 }
178
179 return [
180 'status' => 'success',
181 'message' => __( 'Settings saved successfully.', 'betterdocs' ),
182 ];
183 }
184
185
186 public function export_settings( WP_REST_Request $request ): array {
187 $betterdocs_settings = get_option( 'betterdocs_settings' );
188 $json_str = json_encode( $betterdocs_settings, JSON_PRETTY_PRINT );
189 $file_name = 'betterdocs-settings.json';
190
191 return [
192 'success' => true,
193 'data' => [
194 'filename' => $file_name,
195 'filetype' => 'text/json',
196 'download' => $json_str,
197 ]
198 ];
199 }
200
201 public function import_settings( WP_REST_Request $request ): array {
202 $settings = $request->get_param( 'settings' );
203 // Decode the JSON data into a PHP array
204 $settings = json_decode( $settings, true );
205 $saved = update_option( 'betterdocs_settings', $settings );
206
207 if ( ! $saved ) {
208 return [
209 'status' => 'failed'
210 ];
211 }
212
213 return [
214 'status' => 'success'
215 ];
216 }
217
218 public function import_docs( WP_REST_Request $request ): array {
219 $existing_slug = $request->get_param( 'existing_slug' );
220 $action = $request->get_param( 'action' );
221
222 $files = $request->get_file_params();
223
224 $file = $files['file']['tmp_name'];
225
226 $args = [
227 'fetch_attachments' => true,
228 'existing_slug' => $existing_slug,
229 'action' => $action,
230 'file_type' => $files['file']['type']
231 ];
232
233 $wp_importer = new WPImport( $file, $args );
234
235 return $wp_importer->run();
236 }
237
238 public function parse_xml( WP_REST_Request $request ): array {
239 $data = $request->get_params();
240 $existing_post_slugs = $this->get_existing_slugs( $data['posts'] );
241
242 // Output the array of existing post slugs
243 return [
244 'status' => 'success',
245 'data' => $existing_post_slugs,
246 ];
247 }
248
249 public function parse_csv( WP_REST_Request $request ): array {
250 $files = $request->get_file_params();
251
252 $file = $files['file']['tmp_name'];
253
254 $parser = new CSV_Parser();
255 $parsed = $parser->parse( $file );
256
257 $existing_post_slugs = [];
258
259 if ( isset( $parsed['posts'] ) && is_array( $parsed['posts'] ) ) {
260 $post_names = array_map(
261 function ( $post ) {
262 return $post['post_name'];
263 },
264 $parsed['posts']
265 );
266
267 $existing_post_slugs = $this->get_existing_slugs( $post_names );
268 }
269
270 return [
271 'status' => 'success',
272 'data' => $existing_post_slugs,
273 ];
274 }
275
276 public function migrate_plugins( WP_REST_Request $request ): array {
277 betterdocs()->kbmigration->migrate();
278
279 return [
280 'status' => 'success'
281 ];
282 }
283
284 public function helpscout_migration( WP_REST_Request $request ) {
285 $api_key = $request->get_param( 'helpscout_api_key' );
286 $collection_id = $request->get_param( 'helpscout_collection_id' );
287
288 if ( ! $api_key || ! $collection_id ) {
289 return [
290 'status' => 'error',
291 'message' => esc_html__( 'Please provide both API Key and Collection ID', 'betterdocs' )
292 ];
293 }
294
295 $api_endpoint = 'https://docsapi.helpscout.net/v1/collections/' . $collection_id . '/articles?pageSize=1';
296
297 $headers = array(
298 'Authorization' => 'Basic ' . base64_encode( $api_key . ':X' ),
299 'Content-Type' => 'application/json',
300 );
301
302 $initial_response = wp_remote_get( $api_endpoint, array( 'headers' => $headers ) );
303
304 if ( $initial_response['response']['code'] == '404' ) {
305 return [
306 'status' => 'error',
307 'message' => esc_html__( 'Unauthorized API Key or Collection ID', 'betterdocs' )
308 ];
309 }
310
311 // Enqueue migration task
312 betterdocs()->backgroundProccessor->push_to_queue(
313 array(
314 'headers' => $headers,
315 'initial_response' => $initial_response,
316 'api_key' => $api_key,
317 'collection_id' => $collection_id
318 )
319 )->save();
320
321 // Start processing the queue
322 betterdocs()->backgroundProccessor->dispatch();
323
324 return [
325 'status' => 'success',
326 'message' => esc_html__( 'Migration process has started in the background.', 'betterdocs' )
327 ];
328 }
329
330 public function get_existing_slugs( $slugs ) {
331 // Initialize the array for existing post slugs
332 $existing_post_slugs = [];
333
334 // Initialize the query arguments
335 $args = [
336 'post_type' => [ 'docs', 'betterdocs_faq' ], // Change 'post' to your custom post type if applicable
337 'post_status' => 'publish',
338 'posts_per_page' => -1, // Retrieve all posts
339 'fields' => 'ids', // Retrieve only post IDs to reduce memory usage
340 ];
341
342 // Create a new instance of WP_Query
343 $query = new WP_Query( $args );
344
345 // Get an array of post slugs from the query
346 $all_post_slugs = array_map(
347 function ( $post_id ) {
348 return get_post_field( 'post_name', $post_id );
349 },
350 $query->posts
351 );
352
353 // Restore original post data
354 wp_reset_postdata();
355
356 // Find the intersection of the two arrays to get existing post slugs
357 return array_intersect( $slugs, $all_post_slugs );
358 }
359
360 public function insights(): bool {
361 return true;
362 }
363
364 public function get_settings(): array {
365 return betterdocs()->settings->get_all( true );
366 }
367
368 public function save_settings( WP_REST_Request $request ) {
369 if ( betterdocs()->settings->save_settings( $request->get_params() ) ) {
370 return $this->success( __( 'Settings Saved!', 'betterdocs' ) );
371 }
372
373 return $this->error( 'nothing_changed', __( 'There are no changes to be saved.', 'betterdocs' ), 200 );
374 }
375
376 /**
377 * @throws NotFoundException
378 * @throws DependencyException
379 */
380 public function test_reporting( $request ) {
381 return $this->container->get( ReportEmail::class )->test_email_report( $request );
382 }
383
384 public function do_wizard_tracking(): bool {
385 $insights = betterdocs()->admin->plugin_insights( true );
386 // Get our data
387 $insights->schedule_tracking();
388 $insights->set_is_tracking_allowed( true, 'betterdocs' );
389 if ( $insights->do_tracking( true ) ) {
390 $insights->update_block_notice( 'betterdocs' );
391 }
392 if ( ! isset( $_COOKIE['betterdocs_insights_allowed'] ) ) {
393 setcookie( 'betterdocs_insights_allowed', true, time() + ( 30 * 24 * 60 * 60 ), '/' );
394 }
395 return true;
396 }
397
398 public function plugin_insights( $request ) {
399 if ( $this->do_wizard_tracking() ) {
400 wp_send_json_success( 'done' );
401 }
402 wp_send_json_error( 'Something went wrong.' );
403 }
404 }
405