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

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

244 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 //var_dump($_valid);
196 // Fallback
197 if( ! empty( $_valid ) ) {
198 unset( $wp->query_vars['attachment'] );
199 }
200 }
201 }
202
203 /**
204 * This method is responsible for checking a structure is valid again a request.
205 *
206 * @param string $structure
207 * @param string $request
208 * @return array|bool
209 */
210 private function is_perma_valid_for( $structure, $request ) {
211 if ( empty( $structure ) ) {
212 return false;
213 }
214
215 $_tags = explode( '/', trim( $structure, '/' ) );
216 $_replace_matched_tags = [];
217
218 $_replace_tags = array_filter( $_tags, function ( $item ) use ( &$_replace_matched_tags ) {
219 $_is_valid = strpos( $item, '%' ) !== false;
220 if ( $_is_valid ) {
221 $_replace_matched_tags[] = trim( $item, '%' );
222 }
223 return $_is_valid;
224 } );
225
226 $_perma_structure = preg_quote( $structure, '/' );
227 $_perma_structure = str_replace( $_replace_tags, '([^\/]+)', $_perma_structure );
228
229 preg_match( "/^$_perma_structure$/", $request, $matches );
230
231 if ( empty( $matches ) || ! is_array( $matches ) ) {
232 return false;
233 }
234
235 if ( count( $matches ) === 1 ) {
236 return ['post_type' => 'docs'];
237 }
238
239 unset( $matches[0] );
240
241 return array_combine( $_replace_matched_tags, $matches );
242 }
243 }
244