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

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

310 lines 10.5 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 Error;
6 use WP_Query;
7 use WP_REST_Response;
8 use WPDeveloper\BetterDocs\Core\BaseAPI;
9
10 class Docs extends BaseAPI {
11 public function permission_check(): bool {
12 return true;
13 }
14
15 public function register() {
16 $this->get( 'search', [$this, 'search_posts'] );
17 $this->get( 'search-insert', [$this, 'search_insert'] );
18 $this->get( 'get-terms', [$this, 'get_terms_name_and_slug'] );
19 $this->get( 'months-with-posts', [$this, 'get_months_with_posts'] );
20 $this->register_field( 'docs', 'year_month', [
21 'get_callback' => [$this, 'year_month']
22 ] );
23
24 $this->register_field( 'docs', 'password', [
25 'get_callback' => [$this, 'get_post_password']
26 ] );
27
28 add_filter( 'rest_docs_query', [$this, 'filter_docs_query'], 10, 2 );
29 }
30
31 /**
32 * Retrieves the months and years that have posts of the type 'docs' and formats them.
33 *
34 * This function queries the WordPress database for all unique months and years
35 * in which 'docs' post type posts have been published. The results are then
36 * formatted into an array of associative arrays, where each entry contains an
37 * 'id' and a 'name'.
38 *
39 * The 'id' is a string formatted as 'month-year' (e.g., 'may-2024') to provide
40 * a unique identifier that is easy to work with in JavaScript and HTML. The 'name'
41 * is a more human-readable string formatted as 'Month Year' (e.g., 'May 2024') to
42 * display to users.
43 *
44 * @return WP_REST_Response A response containing the formatted months and years.
45 */
46 public function get_months_with_posts() {
47 global $wpdb;
48
49 // Query to get distinct year and month from posts of type 'docs'
50 $results = $wpdb->get_results(
51 "SELECT DISTINCT YEAR(post_date) AS year, MONTH(post_date) AS month
52 FROM $wpdb->posts
53 WHERE post_type = 'docs'
54 ORDER BY post_date DESC"
55 );
56
57 $formatted_months = [];
58
59 foreach ( $results as $result ) {
60 $year = $result->year;
61 $month = $result->month;
62
63 // Create a DateTime object to format the month
64 $date = \DateTime::createFromFormat( '!m', $month );
65 $month_name = $date->format( 'F' ); // Full month name
66 $month_number = $date->format( 'm' ); // Month number with leading zero
67
68 // Format the months and years into wp rest api structure like wp-json/wp/v2/doc_category
69 $formatted_months[] = [
70 'id' => "$year-$month_number", // e.g., '2024-05'
71 'name' => "$month_name $year" // e.g., 'May 2024'
72 ];
73 }
74
75 return rest_ensure_response( $formatted_months );
76 }
77
78 /**
79 * Callback function to retrieve 'year_month' field value.
80 *
81 * @param object $post The REST API response object.
82 * @return string The formatted date (e.g., '2024-05').
83 */
84 public function year_month( $post ) {
85 $date_string = isset( $post->post_date ) ? $post->post_date : '';
86
87 $date = new \DateTime( $date_string );
88
89 // Format the date to 'Y-m' (e.g., '2024-05')
90 $formatted_date = $date->format( 'Y-m' );
91
92 return $formatted_date;
93 }
94
95 /**
96 * Filter the docs query by year_month parameters.
97 *
98 * @param array $args The query arguments.
99 * @param WP_REST_Request $request The current REST API request.
100 * @return array Modified query arguments.
101 */
102 public function filter_docs_query( $args, $request ) {
103 // Filter by year_month
104 if ( isset( $request['year_month'] ) ) {
105 $formatted_date = $request['year_month'];
106
107 // Parse the formatted_date to year and month
108 $year = substr( $formatted_date, 0, 4 );
109 $month = substr( $formatted_date, 5, 2 );
110
111 // Add date query arguments
112 $args['date_query'] = [
113 [
114 'year' => $year,
115 'month' => $month
116 ]
117 ];
118 }
119
120 return $args;
121 }
122
123
124 public function get_post_password( $object, $field_name, $request ) {
125 if ( current_user_can( 'edit_docs' ) ) {
126 return isset( $object['password'] ) ? $object['password'] : '';
127 } else {
128 return '';
129 }
130 }
131
132 public function search_posts( $request ) {
133 $search_query = sanitize_text_field($request->get_param('s'));
134 $doc_category = sanitize_text_field($request->get_param('doc_category'));
135 $number = (int) $request->get_param('per_page') ? (int) $request->get_param('per_page') : 5;
136 $docs_ids = ! empty( $request->get_param('doc_ids') ) ? explode( ',', $request->get_param('doc_ids') ) : [];
137 $doc_term_ids = ! empty( $request->get_param('doc_categories_ids') ) ? explode(',', $request->get_param('doc_categories_ids')) : [];
138 $faq_term_ids = ! empty( $request->get_param('faq_categories_ids') ) ? explode(',',$request->get_param('faq_categories_ids')) : [];
139 $posts = array();
140
141 // Common query args
142 $common_args = [
143 'post_status' => 'publish',
144 'suppress_filters' => true,
145 'orderby' => 'relevance',
146 ];
147
148 if ( is_plugin_active( 'sitepress-multilingual-cms/sitepress.php' ) ) {
149 $common_args['suppress_filters'] = false;
150 $common_args['lang'] = ICL_LANGUAGE_CODE;
151 }
152
153 if ( $search_query ) {
154 $common_args['s'] = $search_query;
155 $common_args['posts_per_page'] = -1;
156 } else {
157 $common_args['posts_per_page'] = $number;
158 }
159
160 // Docs-specific query
161 $docs_args = array_merge( $common_args, [
162 'post_type' => 'docs'
163 ]);
164
165 if ( ! $search_query ) {
166 $docs_args['meta_key'] = '_betterdocs_meta_views';
167 $docs_args['orderby'] = 'meta_value_num';
168 $docs_args['order'] = 'DESC';
169 }
170
171 if( ! empty( $docs_ids ) ) {
172 unset($docs_args['meta_key']);
173 $docs_args['posts_per_page'] = -1;
174 $docs_args['post__in'] = $docs_ids;
175 }
176
177 if( ! empty( $doc_term_ids ) ) {
178 unset($docs_args['meta_key']);
179 $docs_args['posts_per_page'] = -1;
180 $docs_args['tax_query'] = [
181 [
182 'taxonomy' => 'doc_category',
183 'field' => 'term_id',
184 'terms' => $doc_term_ids,
185 'operator' => 'IN',
186 ]
187 ];
188 }
189
190 // Taxonomy filter for docs
191 if ( $doc_category ) {
192 $docs_args['tax_query'] = [
193 [
194 'taxonomy' => 'doc_category',
195 'field' => 'slug',
196 'terms' => $doc_category,
197 'operator' => 'AND',
198 'include_children' => true,
199 ],
200 ];
201 }
202
203 // FAQ-specific query
204 $faq_args = array_merge( $common_args, [
205 'post_type' => 'betterdocs_faq',
206 'orderby' => 'date',
207 'order' => 'DESC',
208 ]);
209
210 if( ! empty( $faq_term_ids ) ) {
211 $faq_args['posts_per_page'] = -1;
212 $faq_args['tax_query'] = [
213 [
214 'taxonomy' => 'betterdocs_faq_category',
215 'field' => 'term_id',
216 'terms' => $faq_term_ids,
217 'operator' => 'IN',
218 ]
219 ];
220 }
221
222 // Run individual queries
223 $docs_query = betterdocs()->query->get_posts( $docs_args );
224 $faq_query = new WP_Query( $faq_args );
225
226 // Process docs posts
227 if ( $docs_query->have_posts() ) {
228 while ( $docs_query->have_posts() ) {
229 $docs_query->the_post();
230
231 $taxonomies = array();
232 $terms = get_the_terms(get_the_ID(), 'doc_category');
233 if ($terms && !is_wp_error($terms)) {
234 $taxonomies = wp_list_pluck($terms, 'name');
235 }
236
237 $posts[] = array(
238 'title' => get_the_title(),
239 'post_type' => get_post_type(),
240 'permalink' => get_the_permalink(),
241 'taxonomies' => implode(', ', $taxonomies),
242 );
243 }
244 wp_reset_postdata();
245 }
246
247 // Process FAQ posts with content
248 if ( $faq_query->have_posts() ) {
249 while ( $faq_query->have_posts() ) {
250 $faq_query->the_post();
251
252 $terms = get_the_terms(get_the_ID(), 'betterdocs_faq_category');
253 $taxonomies = array();
254 if ($terms && !is_wp_error($terms)) {
255 $taxonomies = wp_list_pluck($terms, 'name');
256 }
257
258 $posts[] = array(
259 'title' => get_the_title(),
260 'content' => get_the_content(), // Include post content for FAQ posts
261 'post_type' => get_post_type(),
262 'permalink' => get_the_permalink(),
263 'taxonomies' => implode(', ', $taxonomies),
264 );
265 }
266 wp_reset_postdata();
267 }
268
269 return $posts;
270 }
271
272
273
274 public function search_insert( $request ) {
275 $search_input = sanitize_text_field($request->get_param('s'));
276 $no_result = sanitize_text_field($request->get_param('no_result'));
277
278 return betterdocs()->query->insert_search_keyword($search_input, $no_result);
279 }
280
281
282 public function get_terms_name_and_slug( $request ) {
283 // Retrieve all terms for the specified taxonomy, including empty ones
284 $terms = get_terms([
285 'taxonomy' => $request->get_param('taxonomy'),
286 'hide_empty' => false,
287 'fields' => 'all',
288 ]);
289
290 // Initialize an empty array to hold the term data
291 $term_data = [];
292
293 // Loop through each term and extract the name and slug
294 $term_data = array_map(function($term) {
295 return [
296 'name' => $term->name,
297 'slug' => $term->slug,
298 'parent' => $term->parent,
299 ];
300 }, $terms);
301
302
303 // Return the array of term data
304 return $term_data;
305 }
306
307 public function get_faq_categories( $request ) {}
308
309 }
310