PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.2.0
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.2.0
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 / FaqSearchedTerms.php

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

184 lines 6.1 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_Error;
6 use WPDeveloper\BetterDocs\Core\BaseAPI;
7
8 class FaqSearchedTerms extends BaseAPI {
9 public function permission_check() {
10 // Only allow logged-in users with FAQ management capabilities
11 return current_user_can( 'read_faq_builder' );
12 }
13
14 public function register() {
15 $this->get( 'faq-terms-by-keyword-search', [$this, 'search_logic'], [
16 'password' => [
17 'description' => __( 'The password for password-protected FAQs.' ),
18 'type' => 'string',
19 ],
20 ] );
21 $this->post( 'faq-accordion-toggle', [$this, 'toggle_enable_disable'] );
22 }
23
24 public function search_logic( $request ) {
25 $keyword = $request->get_param( 'search' );
26
27 if ( empty( $keyword ) ) {
28 $error = new WP_Error( 400, __( 'FAQ Search Parameter Cannot Be Empty', 'betterdocs' ) );
29 return rest_ensure_response( $error );
30 }
31
32 $term_ids = [];
33
34 // Determine allowed post statuses based on user permissions
35 $post_status = ['publish'];
36 if( current_user_can( 'read_private_docs' ) ) {
37 $post_status[] = 'private';
38 }
39
40 $args = [
41 'post_type' => 'betterdocs_faq',
42 'post_status' => $post_status,
43 's' => $keyword,
44 'posts_per_page' => -1
45 ];
46
47 // Exclude password-protected posts unless user has permission
48 if ( ! current_user_can( 'edit_posts' ) ) {
49 $args['has_password'] = false;
50 }
51
52 $query = new \WP_Query( $args );
53 if ( $query->have_posts() ) {
54 while ( $query->have_posts() ) {
55 $query->the_post();
56 $post_obj = get_post( get_the_ID() );
57
58 // Check if user can access password-protected content
59 if ( ! empty( $post_obj->post_password ) ) {
60 $can_access = $this->can_access_password_content( $post_obj, $request );
61 if ( ! $can_access ) {
62 continue; // Skip this FAQ
63 }
64 }
65
66 $categories = get_the_terms( get_the_ID(), 'betterdocs_faq_category' );
67
68 if ( $categories ) {
69 foreach ( $categories as $category ) {
70 $term_ids[] = $category->term_id;
71 }
72 }
73 }
74 wp_reset_postdata();
75 }
76
77 $terms = get_terms(
78 [
79 'taxonomy' => 'betterdocs_faq_category',
80 'hide_empty' => false,
81 'search' => $keyword
82 ]
83 );
84
85 foreach ( $terms as $term ) {
86 $term_ids[] = $term->term_id;
87 }
88
89 $term_ids = array_unique( $term_ids );
90
91 if ( empty( $term_ids ) ) {
92 return rest_ensure_response( [] );
93 }
94
95 $terms_with_meta = [];
96
97 $terms_payload = get_terms(
98 [
99 'taxonomy' => 'betterdocs_faq_category',
100 'hide_empty' => false,
101 'include' => $term_ids
102 ]
103 );
104
105 foreach ( $terms_payload as $term ) {
106 $meta = get_term_meta( $term->term_id );
107 $meta['_betterdocs_faq_order'] = empty( get_term_meta( $term->term_id, '_betterdocs_faq_order', true ) ) ? [] : [get_term_meta( $term->term_id, '_betterdocs_faq_order', true )];
108 $term->meta = $meta;
109 array_push( $terms_with_meta, $term );
110 }
111
112 return rest_ensure_response( $terms_with_meta );
113 }
114
115 public function toggle_enable_disable( $request ) {
116 $body_params = json_decode( $request->get_body() );
117 $faq_id = isset( $body_params->faq_id ) ? $body_params->faq_id : 0;
118 $toggle = $body_params->toggle;
119
120 if ( $faq_id != 0 ) {
121 // Security check: Verify user can edit this FAQ post
122 if ( ! current_user_can( 'edit_post', $faq_id ) ) {
123 return new WP_Error(
124 'rest_cannot_edit',
125 __( 'Sorry, you are not allowed to edit this FAQ.', 'betterdocs' ),
126 array( 'status' => 403 )
127 );
128 }
129
130 // Verify the post is actually a FAQ post type
131 $post = get_post( $faq_id );
132 if ( ! $post || $post->post_type !== 'betterdocs_faq' ) {
133 return new WP_Error(
134 'rest_post_invalid_id',
135 __( 'Invalid FAQ ID.', 'betterdocs' ),
136 array( 'status' => 404 )
137 );
138 }
139
140 $previous_toggle = get_post_meta( $faq_id, 'faq_open_by_default', true );
141 return update_post_meta( $faq_id, 'faq_open_by_default', $toggle, $previous_toggle );
142 }
143
144 return new WP_Error(
145 'rest_missing_callback_param',
146 __( 'FAQ ID is required.', 'betterdocs' ),
147 array( 'status' => 400 )
148 );
149 }
150
151 /**
152 * Checks if the user can access password-protected content.
153 *
154 * This method determines whether we need to override the regular password
155 * check in core with a filter.
156 *
157 * @param WP_Post $post Post to check against.
158 * @param WP_REST_Request $request Request data to check.
159 * @return bool True if the user can access password-protected content, otherwise false.
160 */
161 public function can_access_password_content( $post, $request ) {
162 if ( empty( $post->post_password ) ) {
163 // No filter required.
164 return true;
165 }
166
167 /*
168 * Users always get access to password protected content if they have
169 * the `edit_post` meta capability.
170 */
171 if ( current_user_can( 'edit_post', $post->ID ) ) {
172 return true;
173 }
174
175 // No password provided in request, no auth.
176 if ( empty( $request ) || empty( $request['password'] ) ) {
177 return false;
178 }
179
180 // Double-check the request password.
181 return hash_equals( $post->post_password, $request['password'] );
182 }
183 }
184