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

243 lines 7.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->permalink_magic( $wp );
161 }
162
163 protected function permalink_magic( $wp ) {
164 $this->wp_query_vars = $wp->query_vars;
165
166 if ( ! empty( $this->perma_structure ) ) {
167 $_valid = [];
168
169 foreach ( $this->perma_structure as $_type => $structure ) {
170 $_perma_vars = $this->is_perma_valid_for( $structure, $wp->request );
171
172 // $_valid = empty( $_valid ) && $_perma_vars ? [ 'type' => $_type, 'query_vars' => $_perma_vars ] : $_valid;
173 if ( ( $_perma_vars && method_exists( $this, $_type ) && call_user_func_array( [$this, $_type], [ & $_perma_vars] ) ) ) {
174 // dump( $_type, $_perma_vars );
175 if ( $_type === 'is_single_docs' || $_type == 'is_docs_feed' ) {
176 $_perma_vars['post_type'] = 'docs';
177 }
178 $_valid = ['type' => $_type, 'query_vars' => $_perma_vars];
179 }
180 }
181
182 $type = isset( $_valid['type'] ) ? $_valid['type'] : '';
183 $query_vars = isset( $_valid['query_vars'] ) ? $_valid['query_vars'] : [];
184
185 if ( ! empty( $type ) ) {
186 unset( $this->query_vars[$type] );
187 array_map( function ( $_vars ) use ( &$wp ) {
188 array_map( function ( $_var ) use ( &$wp ) {
189 unset( $wp->query_vars[$_var] );
190 }, $_vars );
191 }, $this->query_vars );
192 }
193
194 $wp->query_vars = is_array( $query_vars ) ? array_merge( $wp->query_vars, $query_vars ) : $wp->query_vars;
195 // Fallback
196 if( ! empty( $_valid ) ) {
197 unset( $wp->query_vars['attachment'] );
198 }
199 }
200 }
201
202 /**
203 * This method is responsible for checking a structure is valid again a request.
204 *
205 * @param string $structure
206 * @param string $request
207 * @return array|bool
208 */
209 private function is_perma_valid_for( $structure, $request ) {
210 if ( empty( $structure ) ) {
211 return false;
212 }
213
214 $_tags = explode( '/', trim( $structure, '/' ) );
215 $_replace_matched_tags = [];
216
217 $_replace_tags = array_filter( $_tags, function ( $item ) use ( &$_replace_matched_tags ) {
218 $_is_valid = strpos( $item, '%' ) !== false;
219 if ( $_is_valid ) {
220 $_replace_matched_tags[] = trim( $item, '%' );
221 }
222 return $_is_valid;
223 } );
224
225 $_perma_structure = preg_quote( $structure, '/' );
226 $_perma_structure = str_replace( $_replace_tags, '([^\/]+)', $_perma_structure );
227
228 preg_match( "/^$_perma_structure$/", $request, $matches );
229
230 if ( empty( $matches ) || ! is_array( $matches ) ) {
231 return false;
232 }
233
234 if ( count( $matches ) === 1 ) {
235 return ['post_type' => 'docs'];
236 }
237
238 unset( $matches[0] );
239
240 return array_combine( $_replace_matched_tags, $matches );
241 }
242 }
243