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

481 lines 20.3 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 }
111 if ($builtin_doc_page == 'off') {
112 $args['has_archive'] = false;
113 $args['rewrite'] = array('slug' => $docs_post_slug, 'with_front' => false);
114 } else {
115 $args['has_archive'] = true;
116 $args['rewrite'] = array('slug' => $docs_post_slug, 'with_front' => false);
117 }
118 register_post_type(self::$post_type, $args);
119 flush_rewrite_rules();
120
121 /**
122 * Register category taxonomy
123 */
124 $category_labels = array(
125 'name' => esc_html__('Docs Categories', 'betterdocs'),
126 'singular_name' => esc_html__('Docs Category', 'betterdocs'),
127 'all_items' => esc_html__('Docs Categories', 'betterdocs'),
128 'parent_item' => esc_html__('Parent Docs Category', 'betterdocs'),
129 'parent_item_colon'=> esc_html__('Parent Docs Category:', 'betterdocs'),
130 'edit_item' => esc_html__('Edit Category', 'betterdocs'),
131 'update_item' => esc_html__('Update Category', 'betterdocs'),
132 'add_new_item' => esc_html__('Add New Docs Category', 'betterdocs'),
133 'new_item_name' => esc_html__('New Docs Name', 'betterdocs'),
134 'menu_name' => esc_html__('Categories', 'betterdocs')
135 );
136
137 $category_args = array(
138 'hierarchical' => true,
139 'public' => true,
140 'labels' => $category_labels,
141 'show_ui' => true,
142 'show_in_rest' => true,
143 'show_admin_column' => true,
144 );
145 $category_slug = BetterDocs_DB::get_settings('category_slug');
146 if ($builtin_doc_page == 1) {
147 $category_args['rewrite'] = array('slug' => $category_slug, 'with_front' => false);
148 } else {
149 $category_args['rewrite'] = array('slug' => 'docs-category', 'with_front' => false);
150 }
151 register_taxonomy(self::$category, array(self::$post_type), $category_args);
152
153 /**
154 * Register tag taxonomy
155 */
156 $tags_labels = array(
157 'name' => esc_html__('Docs Tags', 'betterdocs'),
158 'singular_name' => esc_html__('Tag', 'betterdocs'),
159 'search_items' => esc_html__('Search Tags', 'betterdocs'),
160 'popular_items' => esc_html__('Popular Tags', 'betterdocs'),
161 'all_items' => esc_html__('All Tags', 'betterdocs'),
162 'parent_item' => null,
163 'parent_item_colon' => null,
164 'edit_item' => esc_html__('Edit Tag', 'betterdocs'),
165 'update_item' => esc_html__('Update Tag', 'betterdocs'),
166 'add_new_item' => esc_html__('Add New Tag', 'betterdocs'),
167 'new_item_name' => esc_html__('New Tag Name', 'betterdocs'),
168 'separate_items_with_commas' => esc_html__('Separate tags with commas', 'betterdocs'),
169 'add_or_remove_items' => esc_html__('Add or remove tags', 'betterdocs'),
170 'choose_from_most_used' => esc_html__('Choose from the most used tags', 'betterdocs'),
171 'menu_name' => esc_html__('Tags', 'betterdocs'),
172 );
173 $tag_args = array(
174 'hierarchical' => true,
175 'labels' => $tags_labels,
176 'show_ui' => true,
177 'update_count_callback' => '_update_post_term_count',
178 'show_admin_column' => true,
179 'query_var' => true,
180 'show_in_rest' => true
181 );
182 $tag_slug = BetterDocs_DB::get_settings('tag_slug');
183 if ($tag_slug) {
184 $tag_args['rewrite'] = array('slug' => $tag_slug, 'with_front' => false);
185 } else {
186 $tag_args['rewrite'] = array('slug' => 'docs-tag', 'with_front' => false);
187 }
188 register_taxonomy(self::$tag, array(self::$post_type), $tag_args);
189 }
190
191 /**
192 * Added post type to allowed for rest api
193 *
194 * @param array $post_types Get the docs post types.
195 * @return array
196 *
197 * @since 1.0.0
198 *
199 */
200 public static function rest_api_allowed_post_types($post_types) {
201 $post_types[] = self::$post_type;
202
203 return $post_types;
204 }
205
206 /**
207 * load media for taxonomy category image
208 *
209 * @since 1.0.0
210 */
211 public static function load_media() {
212 wp_enqueue_media();
213 }
214
215 /**
216 * Default the taxonomy's terms' order if it's not set.
217 *
218 * @param string $tax_slug The taxonomy's slug.
219 */
220 public static function default_term_order($tax_slug) {
221 $terms = get_terms($tax_slug, array('hide_empty' => false));
222 $order = self::get_max_taxonomy_order($tax_slug);
223 foreach ($terms as $term) {
224 if (!get_term_meta($term->term_id, 'doc_category_order', true)) {
225 update_term_meta($term->term_id, 'doc_category_order', $order);
226 $order++;
227 }
228 }
229 }
230
231 /**
232 * Order the terms on the admin side.
233 */
234 public static function admin_order_terms() {
235 $screen = function_exists('get_current_screen') ? get_current_screen() : '';
236 if (in_array($screen->id, array('toplevel_page_betterdocs-admin', 'betterdocs_page_betterdocs-settings'))) {
237 self::default_term_order('doc_category');
238 }
239
240 if (!isset($_GET['orderby']) && !empty($screen) && !empty($screen->base) && $screen->base === 'edit-tags' && $screen->taxonomy === 'doc_category') {
241 self::default_term_order($screen->taxonomy);
242 add_filter('terms_clauses', array(__CLASS__, 'set_tax_order'), 10, 3);
243 }
244 }
245
246 /**
247 * Get the maximum doc_category_order for this taxonomy. This will be applied to terms that don't have a tax position.
248 */
249 private static function get_max_taxonomy_order($tax_slug) {
250 global $wpdb;
251 $max_term_order = $wpdb->get_col(
252 $wpdb->prepare(
253 "SELECT MAX( CAST( tm.meta_value AS UNSIGNED ) )
254 FROM $wpdb->terms t
255 JOIN $wpdb->term_taxonomy tt ON t.term_id = tt.term_id AND tt.taxonomy = '%s'
256 JOIN $wpdb->termmeta tm ON tm.term_id = t.term_id WHERE tm.meta_key = 'doc_category_order'",
257 $tax_slug
258 )
259 );
260 $max_term_order = is_array($max_term_order) ? current($max_term_order) : 0;
261 return (int) $max_term_order === 0 || empty($max_term_order) ? 1 : (int) $max_term_order + 1;
262 }
263
264 /**
265 * Re-Order the taxonomies based on the doc_category_order value.
266 *
267 * @param array $pieces Array of SQL query clauses.
268 * @param array $taxonomies Array of taxonomy names.
269 * @param array $args Array of term query args.
270 */
271 public static function set_tax_order($pieces, $taxonomies, $args) {
272 foreach ($taxonomies as $taxonomy) {
273 global $wpdb;
274 if ($taxonomy === 'doc_category') {
275 $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'";
276
277 if (!self::does_substring_exist($pieces['join'], $join_statement)) {
278 $pieces['join'] .= $join_statement;
279 }
280 $pieces['orderby'] = 'ORDER BY CAST( term_meta.meta_value AS UNSIGNED )';
281 }
282 }
283 return $pieces;
284 }
285
286 /**
287 * Order the taxonomies on the front end.
288 */
289 public static function front_end_order_terms() {
290 if (!is_admin()) {
291 add_filter('terms_clauses', array(__CLASS__, 'set_tax_order'), 10, 3);
292 }
293 }
294
295 /**
296 * Check if a substring exists inside a string.
297 *
298 * @param string $string The main string (haystack) we're searching in.
299 * @param string $substring The substring we're searching for.
300 *
301 * @return bool True if substring exists, else false.
302 */
303 protected static function does_substring_exist($string, $substring) {
304 return strstr($string, $substring) !== false;
305 }
306
307 /**
308 * Add a form field in the new category page
309 *
310 * @since 1.0.0
311 */
312 public static function add_doc_category_meta($taxonomy) { ?>
313 <div class="form-field term-group">
314 <label for="doc-category-order"><?php esc_html_e('Order', 'betterdocs'); ?></label>
315 <input type="number" id="doc-category-order" style="width:100px" name="term_meta[order]" value="">
316 </div>
317 <div class="form-field term-group">
318 <label for="doc-category-image-id"><?php esc_html_e('Category Icon', 'betterdocs'); ?></label>
319 <input type="hidden" id="doc-category-image-id" name="term_meta[image-id]" class="custom_media_url" value="">
320 <div id="doc-category-image-wrapper">
321 <?php echo '<img src="' . BETTERDOCS_ADMIN_URL . 'assets/img/betterdocs-cat-icon.svg" alt="">'; ?>
322 </div>
323 <p>
324 <input type="button" class="button button-secondary betterdocs_tax_media_button"
325 id="betterdocs_tax_media_button" name="betterdocs_tax_media_button"
326 value="<?php esc_html_e('Add Image', 'betterdocs'); ?>" />
327 <input type="button" class="button button-secondary doc_tax_media_remove" id="doc_tax_media_remove"
328 name="doc_tax_media_remove"
329 value="<?php esc_html_e('Remove Image', 'betterdocs'); ?>" />
330 </p>
331 </div>
332 <?php
333 }
334
335 /**
336 * Save the form field
337 *
338 * @since 1.0.0
339 */
340 public static function save_doc_category_meta($term_id) {
341 if (isset($_POST['term_meta'])) {
342 $term_meta = get_option("doc_category_$term_id");
343 $cat_keys = array_keys($_POST['term_meta']);
344 foreach ($cat_keys as $key) {
345 if (isset($_POST['term_meta'][$key])) {
346 add_term_meta($term_id, "doc_category_$key", $_POST['term_meta'][$key]);
347 $term_meta[$key] = $_POST['term_meta'][$key];
348 }
349 }
350 }
351 }
352
353 /**
354 * Edit the form field
355 *
356 * @since 1.0.0
357 */
358 public static function update_doc_category_meta($term, $taxonomy) { ?>
359 <?php
360 $term_meta = get_option("doc_category_$term->term_id");
361 $cat_order = get_term_meta($term->term_id, 'doc_category_order', true);
362 $cat_icon_id = get_term_meta($term->term_id, 'doc_category_image-id', true);
363 ?>
364 <tr class="form-field term-group-wrap">
365 <th scope="row">
366 <label for="doc-category-order"><?php esc_html_e('Order', 'betterdocs'); ?></label>
367 </th>
368 <td>
369 <input type="number" id="doc-category-order" style="width:100px" name="term_meta[order]"
370 value="<?php echo $cat_order ? $cat_order : ''; ?>">
371 </td>
372 </tr>
373 <tr class="form-field term-group-wrap batterdocs-cat-media-upload">
374 <th scope="row">
375 <label for="doc-category-image-id"><?php esc_html_e('Image', 'betterdocs'); ?></label>
376 </th>
377 <td>
378 <input type="hidden" id="doc-category-image-id" name="term_meta[image-id]"
379 value="<?php echo $term_meta['image-id'] ? $term_meta['image-id'] : ''; ?>">
380 <div id="doc-category-image-wrapper">
381 <?php
382 if ($cat_icon_id) {
383 echo wp_get_attachment_image($cat_icon_id, 'thumbnail');
384 } else {
385 echo '<img src="' . BETTERDOCS_ADMIN_URL . 'assets/img/betterdocs-cat-icon.svg" alt="">';
386 }
387 ?>
388 </div>
389 <p>
390 <input type="button" class="button button-secondary betterdocs_tax_media_button"
391 id="betterdocs_tax_media_button" name="betterdocs_tax_media_button"
392 value="<?php esc_html_e('Add Image', 'betterdocs'); ?>" />
393 <input type="button" class="button button-secondary doc_tax_media_remove" id="doc_tax_media_remove"
394 name="doc_tax_media_remove"
395 value="<?php esc_html_e('Remove Image', 'betterdocs'); ?>" />
396 </p>
397 </td>
398 </tr>
399 <?php
400 }
401
402 /*
403 * Update the form field value
404 *
405 * @since 1.0.0
406 */
407 public static function updated_doc_category_meta($term_id) {
408 if (isset($_POST['term_meta'])) {
409 $term_meta = get_option("doc_category_$term_id");
410 $cat_keys = array_keys($_POST['term_meta']);
411 foreach ($cat_keys as $key) {
412 if (isset($_POST['term_meta'][$key])) {
413 update_term_meta($term_id, "doc_category_$key", $_POST['term_meta'][$key]);
414 $term_meta[$key] = $_POST['term_meta'][$key];
415 }
416 }
417 }
418 }
419
420 /*
421 * Add script
422 *
423 * @since 1.0.0
424 */
425 public static function add_script() {
426 global $current_screen;
427 if($current_screen->id == 'edit-doc_category'){
428 ?>
429 <script>
430 jQuery(document).ready(function($) {
431 function betterdocs_media_upload(button_class) {
432 var _custom_media = true,
433 _betterdocs_send_attachment = wp.media.editor.send.attachment;
434 $('body').on('click', button_class, function(e) {
435 var button_id = '#' + $(this).attr('id');
436 var send_attachment_bkp = wp.media.editor.send.attachment;
437 var button = $(button_id);
438 _custom_media = true;
439 wp.media.editor.send.attachment = function(props, attachment) {
440 if (_custom_media) {
441 $('#doc-category-image-id').val(attachment.id);
442 $('#doc-category-image-wrapper').html(
443 '<img class="custom_media_image" src="" style="margin:0;padding:0;max-height:100px;float:none;" />'
444 );
445 $('#doc-category-image-wrapper .custom_media_image').attr('src', attachment
446 .url).css('display', 'block');
447 } else {
448 return _betterdocs_send_attachment.apply(button_id, [props, attachment]);
449 }
450 }
451 wp.media.editor.open(button);
452 return false;
453 });
454 }
455 betterdocs_media_upload('.betterdocs_tax_media_button.button');
456 $('body').on('click', '.doc_tax_media_remove', function() {
457 $('#doc-category-image-id').val('');
458 $('#doc-category-image-wrapper').html(
459 '<img class="custom_media_image" src="" style="margin:0;padding:0;max-height:100px;float:none;" />'
460 );
461 });
462
463 $(document).ajaxComplete(function(event, xhr, settings) {
464 var queryStringArr = settings.data.split('&');
465 if ($.inArray('action=add-tag', queryStringArr) !== -1) {
466 var xml = xhr.responseXML;
467 $response = $(xml).find('term_id').text();
468 if ($response != "") {
469 // Clear the thumb image
470 $('#doc-category-image-wrapper').html('');
471 }
472 }
473 });
474 });
475 </script>
476 <?php }
477 }
478 }
479
480 BetterDocs_Docs_Post_Type::init();
481