PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 1.3.2
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v1.3.2
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 / class-betterdocs-docs-post-type.php

class-betterdocs-docs-post-type.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 1.3.2, at includes/class-betterdocs-docs-post-type.php

491 lines 20.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Register docs post type and taxonomies.
4 *
5 * @link https://wpdeveloper.net
6 * @since 1.0.0
7 *
8 * @package BetterDocs
9 * @subpackage BetterDocs/includes
10 */
11
12 /**
13 * Register docs post type and taxonomies class.
14 *
15 *
16 * Also maintains the unique identifier of this plugin as well as the current
17 * version of the plugin.
18 *
19 * @since 1.0.0
20 * @package BetterDocs
21 * @subpackage BetterDocs/includes
22 * @author WPDeveloper <support@wpdeveloper.net>
23 */
24 class BetterDocs_Docs_Post_Type {
25 public static $post_type = 'docs';
26 public static $menu_position = 5;
27 public static $category = 'doc_category';
28 public static $tag = 'doc_tag';
29 /**
30 *
31 * Initialize the class and start calling our hooks and filters
32 *
33 * @since 1.0.0
34 *
35 */
36 public static function init() {
37 add_action('init', array(__CLASS__, 'register_post'));
38 add_filter('rest_api_allowed_post_types', array(__CLASS__, 'rest_api_allowed_post_types'));
39 add_action('admin_head', array(__CLASS__, 'admin_order_terms'));
40 $alphabetically_order_term = BetterDocs_DB::get_settings('alphabetically_order_term');
41 if ( $alphabetically_order_term != 1 ) {
42 add_action('init', array(__CLASS__, 'front_end_order_terms'));
43 }
44 // doc category taxonomy media upload hooks
45 add_action('doc_category_add_form_fields', array(__CLASS__, 'add_doc_category_meta'), 10, 2);
46 add_action('doc_category_edit_form_fields', array(__CLASS__, 'update_doc_category_meta'), 10, 2);
47 add_action('created_doc_category', array(__CLASS__, 'save_doc_category_meta'), 10, 2);
48 add_action('edited_doc_category', array(__CLASS__, 'updated_doc_category_meta'), 10, 2);
49 add_action('admin_enqueue_scripts', array(__CLASS__, 'load_media'));
50 add_action('admin_footer', array(__CLASS__, 'add_script'));
51 }
52
53 /**
54 *
55 * Register post type and taxonomies
56 *
57 * @since 1.0.0
58 *
59 */
60 public static function register_post() {
61 $singular_name = BetterDocs_DB::get_settings('breadcrumb_doc_title');
62 /**
63 * Register post type
64 */
65 $labels = array(
66 'name' => ($singular_name) ? $singular_name : 'Docs',
67 'singular_name' => ($singular_name) ? $singular_name : 'Docs',
68 'menu_name' => esc_html__('BetterDocs', 'betterdocs'),
69 'name_admin_bar' => esc_html__('Docs', 'betterdocs'),
70 'add_new' => esc_html__('Add New', 'betterdocs'),
71 'add_new_item' => esc_html__('Add New Docs', 'betterdocs'),
72 'new_item' => esc_html__('New Docs', 'betterdocs'),
73 'edit_item' => esc_html__('Edit Docs', 'betterdocs'),
74 'view_item' => esc_html__('View Docs', 'betterdocs'),
75 'all_items' => esc_html__('All Docs', 'betterdocs'),
76 'search_items' => esc_html__('Search Docs', 'betterdocs'),
77 'parent_item_colorn' => null,
78 'not_found' => esc_html__('No docs found', 'betterdocs'),
79 'not_found_in_trash' => esc_html__('No docs found in trash', 'betterdocs')
80 );
81 $betterdocs_articles_caps = apply_filters( 'betterdocs_articles_caps', 'edit_posts', 'article_roles' );
82 $args = array(
83 'labels' => $labels,
84 'description' => esc_html__('Add new doc from here', 'betterdocs'),
85 'public' => true,
86 'public_queryable' => true,
87 'exclude_from_search' => false,
88 'show_ui' => true,
89 'show_in_menu' => false,
90 'show_in_admin_bar' => $betterdocs_articles_caps,
91 'query_var' => true,
92 'capability_type' => 'post',
93 'hierarchical' => true,
94 'menu_position' => self::$menu_position,
95 'show_in_rest' => true,
96 'menu_icon' => BETTERDOCS_ADMIN_URL . '/assets/img/betterdocs-icon-white.svg', 100,
97 'supports' => array('title', 'editor', 'thumbnail', 'excerpt', 'author', 'revisions', 'custom-fields', 'comments')
98 );
99 $builtin_doc_page = BetterDocs_DB::get_settings('builtin_doc_page');
100 $docs_slug = BetterDocs_DB::get_settings('docs_slug');
101 $docs_page = BetterDocs_DB::get_settings('docs_page');
102
103 if ( $builtin_doc_page == 1 && $docs_slug ) {
104 $docs_post_slug = $docs_slug;
105 } elseif ( $builtin_doc_page != 1 && $docs_page ) {
106 $post_info = get_post( $docs_page );
107 $docs_post_slug = $post_info->post_name;
108 } elseif ( empty ( $docs_slug ) ) {
109 $docs_post_slug = 'docs';
110 } else {
111 $docs_post_slug = '';
112 }
113 if ($builtin_doc_page == 'off') {
114 $args['has_archive'] = false;
115 $args['rewrite'] = array('slug' => $docs_post_slug, 'with_front' => false);
116 } else {
117 $args['has_archive'] = true;
118 $args['rewrite'] = array('slug' => $docs_post_slug, 'with_front' => false);
119 }
120 register_post_type(self::$post_type, $args);
121 flush_rewrite_rules();
122
123 /**
124 * Register category taxonomy
125 */
126 $category_labels = array(
127 'name' => esc_html__('Docs Categories', 'betterdocs'),
128 'singular_name' => esc_html__('Docs Category', 'betterdocs'),
129 'all_items' => esc_html__('Docs Categories', 'betterdocs'),
130 'parent_item' => esc_html__('Parent Docs Category', 'betterdocs'),
131 'parent_item_colon'=> esc_html__('Parent Docs Category:', 'betterdocs'),
132 'edit_item' => esc_html__('Edit Category', 'betterdocs'),
133 'update_item' => esc_html__('Update Category', 'betterdocs'),
134 'add_new_item' => esc_html__('Add New Docs Category', 'betterdocs'),
135 'new_item_name' => esc_html__('New Docs Name', 'betterdocs'),
136 'menu_name' => esc_html__('Categories', 'betterdocs')
137 );
138
139 $category_args = array(
140 'hierarchical' => true,
141 'public' => true,
142 'labels' => $category_labels,
143 'show_ui' => true,
144 'show_in_rest' => true,
145 'show_admin_column' => true,
146 );
147 $category_slug = BetterDocs_DB::get_settings('category_slug');
148 if ($builtin_doc_page == 1) {
149 $category_args['rewrite'] = array('slug' => $category_slug, 'with_front' => false);
150 } else {
151 $category_args['rewrite'] = array('slug' => 'docs-category', 'with_front' => false);
152 }
153 register_taxonomy(self::$category, array(self::$post_type), $category_args);
154
155 /**
156 * Register tag taxonomy
157 */
158 $tags_labels = array(
159 'name' => esc_html__('Docs Tags', 'betterdocs'),
160 'singular_name' => esc_html__('Tag', 'betterdocs'),
161 'search_items' => esc_html__('Search Tags', 'betterdocs'),
162 'popular_items' => esc_html__('Popular Tags', 'betterdocs'),
163 'all_items' => esc_html__('All Tags', 'betterdocs'),
164 'parent_item' => null,
165 'parent_item_colon' => null,
166 'edit_item' => esc_html__('Edit Tag', 'betterdocs'),
167 'update_item' => esc_html__('Update Tag', 'betterdocs'),
168 'add_new_item' => esc_html__('Add New Tag', 'betterdocs'),
169 'new_item_name' => esc_html__('New Tag Name', 'betterdocs'),
170 'separate_items_with_commas' => esc_html__('Separate tags with commas', 'betterdocs'),
171 'add_or_remove_items' => esc_html__('Add or remove tags', 'betterdocs'),
172 'choose_from_most_used' => esc_html__('Choose from the most used tags', 'betterdocs'),
173 'menu_name' => esc_html__('Tags', 'betterdocs'),
174 );
175 $tag_args = array(
176 'hierarchical' => true,
177 'labels' => $tags_labels,
178 'show_ui' => true,
179 'update_count_callback' => '_update_post_term_count',
180 'show_admin_column' => true,
181 'query_var' => true,
182 'show_in_rest' => true
183 );
184 $tag_slug = BetterDocs_DB::get_settings('tag_slug');
185 if ($tag_slug) {
186 $tag_args['rewrite'] = array('slug' => $tag_slug, 'with_front' => false);
187 } else {
188 $tag_args['rewrite'] = array('slug' => 'docs-tag', 'with_front' => false);
189 }
190 register_taxonomy(self::$tag, array(self::$post_type), $tag_args);
191 }
192
193 /**
194 * Added post type to allowed for rest api
195 *
196 * @param array $post_types Get the docs post types.
197 * @return array
198 *
199 * @since 1.0.0
200 *
201 */
202 public static function rest_api_allowed_post_types($post_types) {
203 $post_types[] = self::$post_type;
204
205 return $post_types;
206 }
207
208 /**
209 * load media for taxonomy category image
210 *
211 * @since 1.0.0
212 */
213 public static function load_media() {
214 wp_enqueue_media();
215 }
216
217 /**
218 * Default the taxonomy's terms' order if it's not set.
219 *
220 * @param string $tax_slug The taxonomy's slug.
221 */
222 public static function default_term_order($tax_slug) {
223 $terms = get_terms($tax_slug, array('hide_empty' => false));
224 $order = self::get_max_taxonomy_order($tax_slug);
225 foreach ($terms as $term) {
226 if (!get_term_meta($term->term_id, 'doc_category_order', true)) {
227 update_term_meta($term->term_id, 'doc_category_order', $order);
228 $order++;
229 }
230 }
231 }
232
233 /**
234 * Order the terms on the admin side.
235 */
236 public static function admin_order_terms() {
237 $screen = function_exists('get_current_screen') ? get_current_screen() : '';
238 if (in_array($screen->id, array('toplevel_page_betterdocs-admin', 'betterdocs_page_betterdocs-settings'))) {
239 self::default_term_order('doc_category');
240 }
241
242 if (!isset($_GET['orderby']) && !empty($screen) && !empty($screen->base) && $screen->base === 'edit-tags' && $screen->taxonomy === 'doc_category') {
243 self::default_term_order($screen->taxonomy);
244 add_filter('terms_clauses', array(__CLASS__, 'set_tax_order'), 10, 3);
245 }
246 }
247
248 /**
249 * Get the maximum doc_category_order for this taxonomy. This will be applied to terms that don't have a tax position.
250 */
251 private static function get_max_taxonomy_order($tax_slug) {
252 global $wpdb;
253 $max_term_order = $wpdb->get_col(
254 $wpdb->prepare(
255 "SELECT MAX( CAST( tm.meta_value AS UNSIGNED ) )
256 FROM $wpdb->terms t
257 JOIN $wpdb->term_taxonomy tt ON t.term_id = tt.term_id AND tt.taxonomy = '%s'
258 JOIN $wpdb->termmeta tm ON tm.term_id = t.term_id WHERE tm.meta_key = 'doc_category_order'",
259 $tax_slug
260 )
261 );
262 $max_term_order = is_array($max_term_order) ? current($max_term_order) : 0;
263 return (int) $max_term_order === 0 || empty($max_term_order) ? 1 : (int) $max_term_order + 1;
264 }
265
266 /**
267 * Re-Order the taxonomies based on the doc_category_order value.
268 *
269 * @param array $pieces Array of SQL query clauses.
270 * @param array $taxonomies Array of taxonomy names.
271 * @param array $args Array of term query args.
272 */
273 public static function set_tax_order($pieces, $taxonomies, $args) {
274 foreach ($taxonomies as $taxonomy) {
275 global $wpdb;
276 if ($taxonomy === 'doc_category') {
277 $join_statement = " LEFT JOIN $wpdb->termmeta AS term_meta ON t.term_id = term_meta.term_id AND term_meta.meta_key = 'doc_category_order'";
278
279 if (!self::does_substring_exist($pieces['join'], $join_statement)) {
280 $pieces['join'] .= $join_statement;
281 }
282 $pieces['orderby'] = 'ORDER BY CAST( term_meta.meta_value AS UNSIGNED )';
283 }
284 }
285 return $pieces;
286 }
287
288 /**
289 * Order the taxonomies on the front end.
290 */
291 public static function front_end_order_terms() {
292 if (!is_admin()) {
293 add_filter('terms_clauses', array(__CLASS__, 'set_tax_order'), 10, 3);
294 }
295 }
296
297 /**
298 * Check if a substring exists inside a string.
299 *
300 * @param string $string The main string (haystack) we're searching in.
301 * @param string $substring The substring we're searching for.
302 *
303 * @return bool True if substring exists, else false.
304 */
305 protected static function does_substring_exist($string, $substring) {
306 return strstr($string, $substring) !== false;
307 }
308
309 /**
310 * Add a form field in the new category page
311 *
312 * @since 1.0.0
313 */
314 public static function add_doc_category_meta($taxonomy) { ?>
315 <div class="form-field term-group">
316 <label for="doc-category-order"><?php esc_html_e('Order', 'betterdocs'); ?></label>
317 <input type="number" id="doc-category-order" style="width:100px" name="term_meta[order]" value="">
318 </div>
319 <div class="form-field term-group">
320 <label for="doc-category-image-id"><?php esc_html_e('Category Icon', 'betterdocs'); ?></label>
321 <input type="hidden" id="doc-category-image-id" name="term_meta[image-id]" class="custom_media_url" value="">
322 <div id="doc-category-image-wrapper">
323 <?php echo '<img src="' . BETTERDOCS_ADMIN_URL . 'assets/img/betterdocs-cat-icon.svg" alt="">'; ?>
324 </div>
325 <p>
326 <input type="button" class="button button-secondary betterdocs_tax_media_button"
327 id="betterdocs_tax_media_button" name="betterdocs_tax_media_button"
328 value="<?php esc_html_e('Add Image', 'betterdocs'); ?>" />
329 <input type="button" class="button button-secondary doc_tax_media_remove" id="doc_tax_media_remove"
330 name="doc_tax_media_remove"
331 value="<?php esc_html_e('Remove Image', 'betterdocs'); ?>" />
332 </p>
333 </div>
334 <?php
335 }
336
337 /**
338 * Save the form field
339 *
340 * @since 1.0.0
341 */
342 public static function save_doc_category_meta($term_id) {
343 if (isset($_POST['term_meta'])) {
344 $term_meta = get_option("doc_category_$term_id");
345 $cat_keys = array_keys($_POST['term_meta']);
346 foreach ($cat_keys as $key) {
347 if (isset($_POST['term_meta'][$key])) {
348 add_term_meta($term_id, "doc_category_$key", $_POST['term_meta'][$key]);
349 $term_meta[$key] = $_POST['term_meta'][$key];
350 }
351 }
352 }
353 }
354
355 /**
356 * Edit the form field
357 *
358 * @since 1.0.0
359 */
360 public static function update_doc_category_meta($term, $taxonomy) { ?>
361 <?php
362 $term_meta = get_option("doc_category_$term->term_id");
363 $cat_order = get_term_meta($term->term_id, 'doc_category_order', true);
364 $cat_icon_id = get_term_meta($term->term_id, 'doc_category_image-id', true);
365 ?>
366 <tr class="form-field term-group-wrap">
367 <th scope="row">
368 <label for="doc-category-id"><?php esc_html_e('Category Id', 'betterdocs'); ?></label>
369 </th>
370 <td>
371 <input type="text" id="doc-category-id" style="width:100px" name="" value="<?php echo $_GET["tag_ID"] ?>" readonly>
372 </td>
373 </tr>
374 <tr class="form-field term-group-wrap">
375 <th scope="row">
376 <label for="doc-category-order"><?php esc_html_e('Order', 'betterdocs'); ?></label>
377 </th>
378 <td>
379 <input type="number" id="doc-category-order" style="width:100px" name="term_meta[order]"
380 value="<?php echo $cat_order ? $cat_order : ''; ?>">
381 </td>
382 </tr>
383 <tr class="form-field term-group-wrap batterdocs-cat-media-upload">
384 <th scope="row">
385 <label for="doc-category-image-id"><?php esc_html_e('Image', 'betterdocs'); ?></label>
386 </th>
387 <td>
388 <input type="hidden" id="doc-category-image-id" name="term_meta[image-id]"
389 value="<?php echo $term_meta['image-id'] ? $term_meta['image-id'] : ''; ?>">
390 <div id="doc-category-image-wrapper">
391 <?php
392 if ($cat_icon_id) {
393 echo wp_get_attachment_image($cat_icon_id, 'thumbnail');
394 } else {
395 echo '<img src="' . BETTERDOCS_ADMIN_URL . 'assets/img/betterdocs-cat-icon.svg" alt="">';
396 }
397 ?>
398 </div>
399 <p>
400 <input type="button" class="button button-secondary betterdocs_tax_media_button"
401 id="betterdocs_tax_media_button" name="betterdocs_tax_media_button"
402 value="<?php esc_html_e('Add Image', 'betterdocs'); ?>" />
403 <input type="button" class="button button-secondary doc_tax_media_remove" id="doc_tax_media_remove"
404 name="doc_tax_media_remove"
405 value="<?php esc_html_e('Remove Image', 'betterdocs'); ?>" />
406 </p>
407 </td>
408 </tr>
409 <?php
410 }
411
412 /*
413 * Update the form field value
414 *
415 * @since 1.0.0
416 */
417 public static function updated_doc_category_meta($term_id) {
418 if (isset($_POST['term_meta'])) {
419 $term_meta = get_option("doc_category_$term_id");
420 $cat_keys = array_keys($_POST['term_meta']);
421 foreach ($cat_keys as $key) {
422 if (isset($_POST['term_meta'][$key])) {
423 update_term_meta($term_id, "doc_category_$key", $_POST['term_meta'][$key]);
424 $term_meta[$key] = $_POST['term_meta'][$key];
425 }
426 }
427 }
428 }
429
430 /*
431 * Add script
432 *
433 * @since 1.0.0
434 */
435 public static function add_script() {
436 global $current_screen;
437 if($current_screen->id == 'edit-doc_category'){
438 ?>
439 <script>
440 jQuery(document).ready(function($) {
441 function betterdocs_media_upload(button_class) {
442 var _custom_media = true,
443 _betterdocs_send_attachment = wp.media.editor.send.attachment;
444 $('body').on('click', button_class, function(e) {
445 var button_id = '#' + $(this).attr('id');
446 var send_attachment_bkp = wp.media.editor.send.attachment;
447 var button = $(button_id);
448 _custom_media = true;
449 wp.media.editor.send.attachment = function(props, attachment) {
450 if (_custom_media) {
451 $('#doc-category-image-id').val(attachment.id);
452 $('#doc-category-image-wrapper').html(
453 '<img class="custom_media_image" src="" style="margin:0;padding:0;max-height:100px;float:none;" />'
454 );
455 $('#doc-category-image-wrapper .custom_media_image').attr('src', attachment
456 .url).css('display', 'block');
457 } else {
458 return _betterdocs_send_attachment.apply(button_id, [props, attachment]);
459 }
460 }
461 wp.media.editor.open(button);
462 return false;
463 });
464 }
465 betterdocs_media_upload('.betterdocs_tax_media_button.button');
466 $('body').on('click', '.doc_tax_media_remove', function() {
467 $('#doc-category-image-id').val('');
468 $('#doc-category-image-wrapper').html(
469 '<img class="custom_media_image" src="" style="margin:0;padding:0;max-height:100px;float:none;" />'
470 );
471 });
472
473 $(document).ajaxComplete(function(event, xhr, settings) {
474 var queryStringArr = settings.data.split('&');
475 if ($.inArray('action=add-tag', queryStringArr) !== -1) {
476 var xml = xhr.responseXML;
477 $response = $(xml).find('term_id').text();
478 if ($response != "") {
479 // Clear the thumb image
480 $('#doc-category-image-wrapper').html('');
481 }
482 }
483 });
484 });
485 </script>
486 <?php }
487 }
488 }
489
490 BetterDocs_Docs_Post_Type::init();
491