PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.6.3
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.6.3
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 / Core / Glossaries.php

Glossaries.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 3.6.3, at includes/Core/Glossaries.php

536 lines 17.9 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\Core;
4
5 use WP_Query;
6 use WP_Error;
7 use WPDeveloper\BetterDocs\Utils\Base;
8
9 class Glossaries extends Base {
10 /**
11 * REST API namespace
12 * @var string
13 */
14 private $namespace = 'betterdocs';
15 public $post_type = 'docs';
16 public $category = 'glossaries';
17
18 /**
19 *
20 * Initialize the class and start calling our hooks and filters
21 *
22 * @since 1.0.0
23 *
24 */
25 public function __construct() {
26 add_action( 'init', [$this, 'register_post'] );
27 // fires after a new betterdocs_glossaries is created
28 add_action( 'created_glossaries', [$this, 'action_created_betterdocs_glossaries'], 10, 2 );
29 add_action( 'rest_api_init', [$this, 'register_api_endpoint'] );
30 add_action('rest_glossaries_query', array($this, 'glossaries_orderby_meta'), 10, 2);
31
32 }
33
34 public function register_post() {
35 register_term_meta( $this->category, 'status', ['show_in_rest' => true, 'single' => true] );
36 }
37
38 public function output() {
39 betterdocs()->views->get( 'admin/glossaries' );
40 }
41
42
43 /**
44 * Default the taxonomy's terms' order if it's not set.
45 *
46 * @param string $tax_slug The taxonomy's slug.
47 */
48 public function action_created_betterdocs_glossaries( $term_id ) {
49 $order = $this->get_max_taxonomy_order( 'glossaries' );
50 // update_term_meta( $term_id, 'order', $order++ );
51 update_term_meta( $term_id, 'status', 1 );
52 }
53
54 /**
55 * Default the taxonomy's terms' order if it's not set.
56 *
57 * @param string $tax_slug The taxonomy's slug.
58 */
59 public function default_term_order( $tax_slug ) {
60 $terms = get_terms( $tax_slug, ['hide_empty' => false] );
61 $order = $this->get_max_taxonomy_order( $tax_slug );
62
63 foreach ( $terms as $term ) {
64 if ( ! get_term_meta( $term->term_id, 'order', true ) ) {
65 update_term_meta( $term->term_id, 'order', $order );
66 $order++;
67 }
68 }
69 }
70
71 /**
72 * Get the maximum order for this taxonomy. This will be applied to terms that don't have a tax position.
73 */
74 private function get_max_taxonomy_order( $tax_slug ) {
75 global $wpdb;
76
77 $max_term_order = $wpdb->get_col(
78 $wpdb->prepare(
79 "SELECT MAX( CAST( tm.meta_value AS UNSIGNED ) )
80 FROM $wpdb->terms t
81 JOIN $wpdb->term_taxonomy tt ON t.term_id = tt.term_id AND tt.taxonomy = '%s'
82 JOIN $wpdb->termmeta tm ON tm.term_id = t.term_id WHERE tm.meta_key = 'order'",
83 $tax_slug
84 )
85 );
86
87 $max_term_order = is_array( $max_term_order ) ? current( $max_term_order ) : 0;
88
89 return (int) $max_term_order === 0 || empty( $max_term_order ) ? 1 : (int) $max_term_order + 1;
90 }
91
92 /**
93 * Re-Order the taxonomies based on the order value.
94 *
95 * @param array $pieces Array of SQL query clauses.
96 * @param array $taxonomies Array of taxonomy names.
97 * @param array $args Array of term query args.
98 */
99 public function set_tax_order( $pieces, $taxonomies, $args ) {
100 foreach ( $taxonomies as $taxonomy ) {
101 global $wpdb;
102
103 if ( $taxonomy === 'betterdocs_glossaries' ) {
104 $join_statement = " LEFT JOIN $wpdb->termmeta AS term_meta ON t.term_id = term_meta.term_id AND term_meta.meta_key = 'order'";
105
106 if ( ! $this->does_substring_exist( $pieces['join'], $join_statement ) ) {
107 $pieces['join'] .= $join_statement;
108 }
109
110 $pieces['orderby'] = 'ORDER BY CAST( term_meta.meta_value AS UNSIGNED )';
111 }
112 }
113
114 return $pieces;
115 }
116
117 /**
118 * Order the taxonomies on the front end.
119 */
120 public function front_end_order_terms() {
121 if ( ! is_admin() ) {
122 add_filter( 'terms_clauses', [$this, 'set_tax_order'], 10, 3 );
123 }
124 }
125
126 /**
127 * Check if a substring exists inside a string.
128 *
129 * @param string $string The main string (haystack) we're searching in.
130 * @param string $substring The substring we're searching for.
131 *
132 * @return bool True if substring exists, else false.
133 */
134 protected function does_substring_exist( $string, $substring ) {
135 return strstr( $string, $substring ) !== false;
136 }
137
138 public function register_api_endpoint() {
139 register_rest_route( $this->namespace, '/glossary/sample_data', [
140 'methods' => ['POST'],
141 'callback' => [$this, 'create_glossary_sample'],
142 'permission_callback' => function () {
143 return current_user_can( 'edit_others_posts' );
144 }
145 ] );
146
147 register_rest_route( $this->namespace, '/glossary/posts/(?P<type>\S+)', [
148 'methods' => ['GET'],
149 'callback' => [$this, 'fetch_faq_posts'],
150 'permission_callback' => '__return_true'
151 ] );
152
153 register_rest_route( $this->namespace, '/glossary/create_glossary', [
154 'methods' => ['POST'],
155 'callback' => [$this, 'create_glossaries'],
156 'permission_callback' => function () {
157 return current_user_can( 'edit_others_posts' );
158 }
159 ] );
160
161 register_rest_route( $this->namespace, '/glossary/update_glossary', [
162 'methods' => ['POST'],
163 'callback' => [$this, 'update_glossaries'],
164 'permission_callback' => function () {
165 return current_user_can( 'edit_others_posts' );
166 }
167 ] );
168
169 register_rest_route( $this->namespace, '/glossary/delete_glossary', [
170 'methods' => ['POST'],
171 'callback' => [$this, 'delete_glossaries'],
172 'permission_callback' => function () {
173 return current_user_can( 'edit_others_posts' );
174 }
175 ] );
176
177
178 register_rest_route( $this->namespace, '/glossary/glossary_status', [
179 'methods' => ['POST'],
180 'callback' => [$this, 'update_glossary_status'],
181 'permission_callback' => function () {
182 return current_user_can( 'edit_others_posts' );
183 }
184 ] );
185
186 register_rest_route( $this->namespace, '/glossary/glossaries_order', [
187 'methods' => ['POST'],
188 'callback' => [$this, 'update_glossaries_order'],
189 'permission_callback' => function () {
190 return current_user_can( 'edit_others_posts' );
191 }
192 ] );
193
194 register_rest_route( $this->namespace, '/glossary/update_order_by_glossary', [
195 'methods' => ['POST'],
196 'callback' => [$this, 'update_faq_order_by_glossary'],
197 'permission_callback' => function () {
198 return current_user_can( 'edit_others_posts' );
199 }
200 ] );
201
202 register_rest_route( $this->namespace, '/glossary/glossary_search', [
203 'methods' => ['GET'],
204 'callback' => [$this, 'glossary_search'],
205 'permission_callback' => '__return_true',
206 'args' => array(
207 'title' => array(
208 'type' => 'string',
209 'required' => true
210 ),
211 ),
212 ] );
213
214
215 register_rest_route( $this->namespace, '/glossary/glossary_count', [
216 'methods' => ['GET'],
217 'callback' => [$this, 'get_glossary_count'],
218 'permission_callback' => function () {
219 return current_user_can( 'edit_others_posts' );
220 }
221 ] );
222 register_rest_route( $this->namespace, '/glossary/get_glossaries', [
223 'methods' => ['GET'],
224 'callback' => [$this, 'get_glossaries'],
225 'permission_callback' => function () {
226 return current_user_can( 'edit_others_posts' );
227 }
228 ] );
229
230
231
232 }
233
234 public function create_glossary_sample( $params ) {
235 $sample_data = json_decode( $params->get_param( 'sample_data' ), true );
236 foreach ( $sample_data as $key => $value ) {
237 $insert_term = wp_insert_term(
238 $key,
239 'glossaries'
240 );
241 if ( $insert_term ) {
242 foreach ( $value['posts'] as $key => $value ) {
243 $this->insert_betterdocs_faq( $value['post_title'], $value['post_content'], $insert_term['term_id'] );
244 }
245 }
246 }
247 return true;
248 }
249
250 public function create_glossaries( $params ) {
251 $title = $params->get_param( 'title' );
252 $description = $params->get_param( 'description' );
253 $slug = $params->get_param( 'slug' );
254
255 return $this->insert_betterdocs_glossaries( $title, $description, $slug );
256 }
257
258 public function update_glossaries( $request ) {
259 $params = $request->get_params();
260
261 $term_id = $request->get_param( 'term_id' );
262 $title = $request->get_param( 'title' );
263 $description = $request->get_param( 'description' );
264 $description = ( $description !== 'undefined' ) ? $description : '';
265 $slug = $request->get_param( 'slug' );
266 $update = wp_update_term( $term_id, 'glossaries', [
267 'name' => $title,
268 'slug' => $slug,
269 'description' => $description
270 ] );
271
272 if ( is_wp_error( $update ) ) {
273 return $update;
274 } else {
275 return true;
276 }
277 }
278
279
280 public function delete_glossaries( $params ) {
281 $term_id = $params->get_param( 'term_id' );
282 $delete = wp_delete_term( $term_id, 'glossaries' );
283
284 if ( is_wp_error( $delete ) ) {
285 return $delete;
286 } else {
287 return true;
288 }
289 }
290
291 public function insert_betterdocs_glossaries( $title, $description, $slug = '' ) {
292 $insert_term = wp_insert_term(
293 $title,
294 'glossaries',
295 [
296 'slug' => $slug,
297 'description' => $description
298 ]
299 );
300
301 if ( is_wp_error( $insert_term ) ) {
302 return $insert_term;
303 } else {
304 return true;
305 }
306 }
307
308 public function update_glossaries_order( $params ) {
309 $glossaries_order = $params->get_param( 'glossaries_order' );
310 $glossaries_order = json_decode( $glossaries_order, true );
311
312 foreach ( $glossaries_order as $order_data ) {
313 if ( (int) $order_data['current_position'] != (int) $order_data['updated_position'] ) {
314 update_term_meta( $order_data['id'], 'order', ( (int) $order_data['updated_position'] ) );
315 }
316 }
317 return true;
318 }
319
320 public function insert_betterdocs_faq( $post_title, $post_content, $term_id ) {
321 $post = wp_insert_post(
322 [
323 'post_type' => 'betterdocs_faq',
324 'post_title' => wp_strip_all_tags( $post_title ),
325 'post_content' => $post_content,
326 'post_status' => 'publish'
327 ]
328 );
329
330 if ( $term_id ) {
331 $set_terms = wp_set_object_terms( $post, $term_id, 'glossaries' );
332 if ( is_wp_error( $set_terms ) ) {
333 return $set_terms;
334 } else {
335 return $this->update_faq_order_on_insert( $term_id, $post );
336 }
337 } else {
338 return $post;
339 }
340 }
341
342 public function update_faq_order_on_insert( $term_id, $post ) {
343 $term_meta = get_term_meta( $term_id, '_betterdocs_faq_order' );
344 if ( ! empty( $term_meta ) ) {
345 $term_meta_arr = explode( ",", $term_meta[0] );
346 if ( ! in_array( $post, $term_meta_arr ) ) {
347 array_unshift( $term_meta_arr, $post );
348 $docs_ordering_data = filter_var_array( wp_unslash( $term_meta_arr ), FILTER_SANITIZE_NUMBER_INT );
349 return update_term_meta( $term_id, '_betterdocs_faq_order', implode( ',', $docs_ordering_data ) );
350 }
351 } else {
352 return update_term_meta( $term_id, '_betterdocs_faq_order', $post );
353 }
354 }
355
356 /**
357 * Update _betterdocs_faq_order meta when new post created
358 */
359
360 public function update_faq_order_by_glossary( $params ) {
361 $term_id = $params->get_param( 'term_id' );
362 $posts = $params->get_param( 'posts' );
363 return update_term_meta( $term_id, '_betterdocs_faq_order', $posts );
364 }
365
366 public function create_betterdocs_faq( $params ) {
367 $post_title = $params->get_param( 'post_title' );
368 $post_content = $params->get_param( 'post_content' );
369 $term_id = $params->get_param( 'term_id' );
370 return $this->insert_betterdocs_faq( $post_title, $post_content, $term_id );
371 }
372
373 public function update_betterdocs_faq( $params ) {
374 $post_id = $params->get_param( 'post_id' );
375 $post_title = $params->get_param( 'post_title' );
376 $post_content = $params->get_param( 'post_content' );
377 $status = $params->get_param( 'status' );
378 $term_id = $params->get_param( 'term_id' );
379 if ( $status ) {
380 $data = [
381 'post_type' => 'betterdocs_faq',
382 'ID' => $post_id,
383 'status' => $status
384 ];
385 } else {
386 $data = [
387 'post_type' => 'betterdocs_faq',
388 'ID' => $post_id,
389 'post_title' => $post_title,
390 'post_content' => $post_content
391 ];
392
393 if ( $term_id ) {
394 $data['tax_input'] = [
395 "betterdocs_glossaries" => $term_id
396 ];
397
398 $term_meta = get_term_meta( $term_id, '_betterdocs_faq_order' );
399 $term_meta_arr = explode( ",", $term_meta[0] );
400 if ( ! in_array( $post_id, $term_meta_arr ) ) {
401 array_unshift( $term_meta_arr, $post_id );
402 $docs_ordering_data = filter_var_array( wp_unslash( $term_meta_arr ), FILTER_SANITIZE_NUMBER_INT );
403 update_term_meta( $term_id, '_betterdocs_faq_order', implode( ',', $docs_ordering_data ) );
404 }
405 }
406 }
407
408 return wp_update_post( $data );
409 }
410
411 public function delete_betterdocs_faq( $params ) {
412 $post_id = $params->get_param( 'post_id' );
413 return wp_delete_post( $post_id );
414 }
415
416 public function faq_post_loop( $args ) {
417 $posts = [];
418 $query = new WP_Query( $args );
419 if ( $query->have_posts() ):
420 while ( $query->have_posts() ): $query->the_post();
421 $posts[get_the_ID()]['title'] = get_the_title();
422 $posts[get_the_ID()]['content'] = get_the_content();
423 endwhile;
424 endif;
425
426 return $posts;
427 }
428
429 public function update_glossary_status( $params ) {
430 $term_id = $params->get_param( 'term_id' );
431 $status = $params->get_param( 'status' );
432 return update_term_meta( $term_id, 'status', $status );
433 }
434
435 public function fetch_faq_posts( $params ) {
436 $faq = [];
437 $type = $params->get_param( 'type' );
438
439 if ( $type == 'category' ) {
440 $taxonomy_objects = get_terms( 'glossaries', [
441 'hide_empty' => false
442 ] );
443
444 if ( $taxonomy_objects && ! is_wp_error( $taxonomy_objects ) ):
445 foreach ( $taxonomy_objects as $term ):
446 $args = [
447 'post_type' => 'betterdocs_faq',
448 'post_status' => 'publish',
449 'post_per_page' => -1,
450 'tax_query' => [
451 [
452 'taxonomy' => 'glossaries',
453 'field' => 'term_id',
454 'terms' => $term->term_id
455 ]
456 ]
457 ];
458
459 $posts = $this->faq_post_loop( $args );
460
461 $faq[$term->slug] = [
462 (array) $term,
463 'posts' => $posts
464 ];
465 endforeach;
466 endif;
467 } else {
468 $args = [
469 'post_type' => 'betterdocs_faq',
470 'post_status' => 'publish',
471 'post_per_page' => -1
472 ];
473 $posts = $this->faq_post_loop( $args );
474 $faq['posts'] = $posts;
475 }
476
477 return $faq;
478 }
479
480
481 public function glossary_search( $request ) {
482
483 $title = $request['title'];
484
485 // Perform the taxonomy search
486 $taxonomy_args = array(
487 'name__like' => $title,
488 'taxonomy' => 'glossaries',
489 'hide_empty' => false
490 );
491
492 $taxonomies = get_terms($taxonomy_args);
493
494 if (!empty($taxonomies)) {
495 $result = array();
496 foreach ($taxonomies as $taxonomy) {
497 $result[] = array(
498 'id' => $taxonomy->term_id,
499 'count' => $taxonomy->count,
500 'description' => $taxonomy->description,
501 'name' => $taxonomy->name,
502 'slug' => $taxonomy->slug
503 // Add more fields as needed
504 );
505 }
506 // Return the taxonomy data
507 return $result;
508 } else {
509 // Taxonomy not found
510 return new WP_Error('taxonomy_not_found', 'Taxonomy not found.', array('status' => 404));
511 }
512 }
513
514 public function glossaries_orderby_meta($args, $request) {
515 if ($args['taxonomy'] === 'glossaries') {
516 $args['orderby'] = 'meta_value_num';
517 $args['meta_key'] = 'status';
518 }
519 return $args;
520 }
521
522 public function get_glossary_count($request) {
523 $options = get_option('store_glossary_count');
524 return rest_ensure_response($options);
525 }
526 public function get_glossaries($request) {
527 $taxo = get_taxonomies( array(
528 'name' => array(
529 'glossaries'
530 )
531 ), 'objects' );
532
533 return rest_ensuree_response( $taxo );
534 }
535 }
536