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

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

257 lines 6.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\Core;
4
5 use WPDeveloper\BetterDocs\Utils\Base;
6
7 class Request extends Base {
8 /**
9 * Flag for already parsed or not
10 *
11 * Specially needed for those who don't update pro yet.
12 * @var boolean
13 */
14 protected static $already_parsed = false;
15
16 /**
17 * List of BetterDocs Perma Structure
18 * @var array
19 */
20 private $perma_structure = [];
21
22 /**
23 * List of BetterDocs Query Vars Agains Page Structure.
24 * @var array
25 */
26 private $query_vars = [];
27
28 /**
29 * List of Query Variables from $wp->query_vars.
30 * @var array
31 */
32 private $wp_query_vars = [];
33
34 /**
35 * Rewrite Class Reference of BetterDocs
36 * @var Rewrite
37 */
38 protected $rewrite;
39
40 /**
41 * Settings Class Reference of BetterDocs
42 * @var Settings
43 */
44 protected $settings;
45
46 public function __construct( Rewrite $rewrite, Settings $settings ) {
47 $this->rewrite = $rewrite;
48 $this->settings = $settings;
49 }
50
51 public function init() {
52 if ( is_admin() ) {
53 return;
54 }
55
56 $this->perma_structure = [
57 'is_docs' => trim( $this->rewrite->get_base_slug(), '/' ),
58 'is_docs_feed' => trim( $this->rewrite->get_base_slug(), '/' ) . '/%feed%',
59 'is_docs_category' => trim( $this->settings->get( 'category_slug', 'docs-category' ), '/' ) . '/%doc_category%',
60 'is_docs_tag' => trim( $this->settings->get( 'tag_slug', 'docs-tag' ), '/' ) . '/%doc_tag%',
61 'is_single_docs' => trim( $this->settings->get( 'permalink_structure', 'docs' ), '/' ) . '/%name%'
62 ];
63
64 $this->query_vars = [
65 'is_docs' => [ 'post_type' ],
66 'is_docs_feed' => [ 'doc_category' ],
67 'is_docs_category' => [ 'doc_category' ],
68 'is_docs_tag' => [ 'doc_tag' ],
69 'is_single_docs' => [ 'name', 'docs', 'post_type' ]
70 ];
71
72 add_action( 'parse_request', [ $this, 'parse' ] );
73
74 /**
75 * This is for Backward compatibility if pro not updated.
76 */
77 add_action( 'parse_request', [ $this, 'backward_compability' ], 11 );
78
79 /**
80 * Make Compatible With Permalink Manager Plugin
81 */
82 add_filter( 'permalink_manager_detected_element_id', [ $this, 'provide_compatibility' ], 10, 3 );
83 }
84
85 public function provide_compatibility( $element_id, $uri_parts, $request_url ) {
86 if ( $request_url == $this->settings->get( 'docs_slug' ) ) {
87 $element_id = '';
88 }
89 return $element_id;
90 }
91
92 protected function is_docs( &$query_vars ) {
93 if ( ! $this->settings->get( 'builtin_doc_page', true ) ) {
94 $query_vars['post_type'] = 'page';
95 $query_vars['name'] = trim( $this->rewrite->get_base_slug(), '/' );
96 }
97
98 return $query_vars;
99 }
100
101 public function is_docs_feed( $query_vars ) {
102 global $wp_rewrite;
103 return isset( $query_vars['feed'] ) && in_array( $query_vars['feed'], $wp_rewrite->feeds );
104 }
105
106 protected function is_single_docs( $query_vars ) {
107 if ( ! isset( $query_vars['name'] ) ) {
108 return false;
109 }
110
111 global $wpdb;
112 $name = $query_vars['name'];
113
114 $_post_id = (int) $wpdb->get_var(
115 $wpdb->prepare(
116 "SELECT ID FROM {$wpdb->posts} WHERE post_name = %s AND post_type = %s LIMIT 1",
117 esc_sql( $name ),
118 'docs'
119 )
120 );
121
122 return $_post_id > 0;
123 }
124
125 protected function is_docs_category( $query_vars ) {
126 return $this->term_exists( $query_vars, 'doc_category' );
127 }
128
129 protected function is_docs_tag( $query_vars ) {
130 return $this->term_exists( $query_vars, 'doc_tag' );
131 }
132
133 protected function term_exists( $query_vars, $taxonomy ) {
134 if ( ! isset( $query_vars[ $taxonomy ] ) ) {
135 return false;
136 }
137
138 return term_exists( $query_vars[ $taxonomy ], $taxonomy );
139 }
140
141 public function set_perma_structure( $structures = [] ) {
142 $this->perma_structure = array_merge( $this->perma_structure, $structures );
143 }
144
145 public function set_query_vars( $query_vars = [] ) {
146 $this->query_vars = array_merge( $this->query_vars, $query_vars );
147 }
148
149 public function backward_compability( $wp ) {
150 if ( static::$already_parsed ) {
151 return;
152 }
153
154 $this->permalink_magic( $wp );
155 }
156
157 public function parse( $wp ) {
158 static::$already_parsed = true;
159
160 $this->perma_structure = apply_filters('docs_rewrite_rules', $this->perma_structure);
161
162 $this->permalink_magic( $wp );
163 }
164
165 protected function permalink_magic( $wp ) {
166 $this->wp_query_vars = $wp->query_vars;
167
168 if ( ! empty( $this->perma_structure ) ) {
169 $_valid = [];
170
171 foreach ( $this->perma_structure as $_type => $structure ) {
172 $_perma_vars = $this->is_perma_valid_for( $structure, $wp->request );
173
174 // $_valid = empty( $_valid ) && $_perma_vars ? [ 'type' => $_type, 'query_vars' => $_perma_vars ] : $_valid;
175 if ( ( $_perma_vars && method_exists( $this, $_type ) && call_user_func_array( [ $this, $_type ], [ & $_perma_vars ] ) ) ) {
176 // dump( $_type, $_perma_vars );
177 if ( $_type === 'is_single_docs' || $_type == 'is_docs_feed' ) {
178 $_perma_vars['post_type'] = 'docs';
179 }
180 $_valid = [
181 'type' => $_type,
182 'query_vars' => $_perma_vars
183 ];
184 }
185 }
186
187 $type = isset( $_valid['type'] ) ? $_valid['type'] : '';
188 $query_vars = isset( $_valid['query_vars'] ) ? $_valid['query_vars'] : [];
189
190 if ( ! empty( $type ) ) {
191 unset( $this->query_vars[ $type ] );
192 array_map(
193 function ( $_vars ) use ( &$wp ) {
194 array_map(
195 function ( $_var ) use ( &$wp ) {
196 unset( $wp->query_vars[ $_var ] );
197 },
198 $_vars
199 );
200 },
201 $this->query_vars
202 );
203 }
204
205 $wp->query_vars = is_array( $query_vars ) ? array_merge( $wp->query_vars, $query_vars ) : $wp->query_vars;
206 // Fallback
207 if ( ! empty( $_valid ) ) {
208 unset( $wp->query_vars['attachment'] );
209 }
210 }
211 }
212
213 /**
214 * This method is responsible for checking a structure is valid again a request.
215 *
216 * @param string $structure
217 * @param string $request
218 * @return array|bool
219 */
220 private function is_perma_valid_for( $structure, $request ) {
221 if ( empty( $structure ) ) {
222 return false;
223 }
224
225 $_tags = explode( '/', trim( $structure, '/' ) );
226 $_replace_matched_tags = [];
227
228 $_replace_tags = array_filter(
229 $_tags,
230 function ( $item ) use ( &$_replace_matched_tags ) {
231 $_is_valid = strpos( $item, '%' ) !== false;
232 if ( $_is_valid ) {
233 $_replace_matched_tags[] = trim( $item, '%' );
234 }
235 return $_is_valid;
236 }
237 );
238
239 $_perma_structure = preg_quote( $structure, '/' );
240 $_perma_structure = str_replace( $_replace_tags, '([^\/]+)', $_perma_structure );
241
242 preg_match( "/^$_perma_structure$/", $request, $matches );
243
244 if ( empty( $matches ) || ! is_array( $matches ) ) {
245 return false;
246 }
247
248 if ( count( $matches ) === 1 ) {
249 return [ 'post_type' => 'docs' ];
250 }
251
252 unset( $matches[0] );
253
254 return array_combine( $_replace_matched_tags, $matches );
255 }
256 }
257