PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.8.9
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.8.9
4.9.2 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 All 200 releases
← All changes | includes/Core/Rewrite.php +240 -188 3.4.23.8.9 View file →
@@ -6,233 +6,285 @@
6 6 use WPDeveloper\BetterDocs\Utils\Base;
7 7 use WPDeveloper\BetterDocs\Utils\Database;
8 8
9 9 class Rewrite extends Base {
10 - protected $settings;
11 - protected $database;
10 + protected $settings;
11 + protected $database;
12 12
13 - public function __construct( Settings $settings, Database $database ) {
14 - $this->settings = $settings;
15 - $this->database = $database;
16 - }
13 + public function __construct( Settings $settings, Database $database ) {
14 + $this->settings = $settings;
15 + $this->database = $database;
16 + }
17 17
18 - public function init() {
19 - add_action( 'init', [$this, 'rules'] );
20 - add_action( 'betterdocs::settings::saved', [$this, 'save_permalink_structure'], 2, 3 );
21 - }
18 + public function init() {
19 + add_action( 'init', [ $this, 'rules' ] );
20 + add_action( 'betterdocs::settings::saved', [ $this, 'save_permalink_structure' ], 2, 3 );
21 + add_action( 'template_redirect', [ $this, 'handle_pagination_redirect' ] );
22 + }
22 23
23 - public function remove_knowledge_base_placeholder( $permalink ) {
24 - $permalink_array = $this->permalink_structure( $permalink, 'arraywithpercent' );
25 - $permalink_array = array_filter( $permalink_array, function ( $item ) {
26 - return $item !== '%knowledge_base%';
27 - } );
24 + /**
25 + * Handle pagination redirect
26 + * Redirects pagination attempts to main archive
27 + */
28 + public function handle_pagination_redirect() {
29 + if ( ! is_post_type_archive( 'docs' ) ) {
30 + return;
31 + }
28 32
29 - return trailingslashit( implode( '/', $permalink_array ) );
30 - }
33 + $paged = get_query_var( 'paged' );
34 + if ( $paged > 1 ) {
35 + global $wp_query;
36 + $wp_query->set_404();
37 + status_header( 404 );
38 + nocache_headers();
39 + }
40 + }
31 41
32 - /**
33 - * This method is hooked with an action called 'betterdocs::settings::saved'
34 - *
35 - * @since 2.5.0
36 - *
37 - * @param bool $_saved
38 - * @param array $_settings
39 - * @param array $_old_settings
40 - *
41 - * @return void
42 - */
43 - public function save_permalink_structure( $_saved, $_settings, $_old_settings ) {
44 - if ( ! isset($_settings['permalink_structure']) ) {
45 - return;
46 - }
42 + public function remove_knowledge_base_placeholder( $permalink ) {
43 + $permalink_array = $this->permalink_structure( $permalink, 'arraywithpercent' );
44 + $permalink_array = array_filter(
45 + $permalink_array,
46 + function ( $item ) {
47 + return $item !== '%knowledge_base%';
48 + }
49 + );
47 50
48 - $_permalink_structure = $_settings['permalink_structure'];
51 + return trailingslashit( implode( '/', $permalink_array ) );
52 + }
49 53
50 - /**
51 - * TODO: Let's re-check later to optimize it.
52 - */
53 - if ( ! betterdocs()->is_pro_active() ) {
54 - $_permalink_structure = $this->remove_knowledge_base_placeholder( $_permalink_structure );
55 - }
54 + /**
55 + * This method is hooked with an action called 'betterdocs::settings::saved'
56 + *
57 + * @since 2.5.0
58 + *
59 + * @param bool $_saved
60 + * @param array $_settings
61 + * @param array $_old_settings
62 + *
63 + * @return void
64 + */
65 + public function save_permalink_structure( $_saved, $_settings, $_old_settings ) {
66 + if ( ! isset( $_settings['permalink_structure'] ) ) {
67 + return;
68 + }
56 69
57 - if ( $_permalink_structure !== $_old_settings['permalink_structure'] ) {
58 - $this->settings->save( 'permalink_structure', $this->permalink_structure( $_permalink_structure ) );
59 - }
70 + $_permalink_structure = $_settings['permalink_structure'];
60 71
61 - /**
62 - * This block of code decides whether it needs to be flushed or not.
63 - * Flush happens after register the post type.
64 - */
65 - switch ( true ) {
66 - case $_permalink_structure !== $_old_settings['permalink_structure']:
67 - case $_settings['docs_slug'] !== $_old_settings['docs_slug']:
68 - case $_settings['builtin_doc_page'] !== $_old_settings['builtin_doc_page']:
69 - case $_settings['docs_page'] !== $_old_settings['docs_page']:
70 - case $_settings['tag_slug'] !== $_old_settings['tag_slug']:
71 - case $_settings['category_slug'] !== $_old_settings['category_slug']:
72 - $this->database->set_transient( 'betterdocs_flush_rewrite_rules', true );
73 - break;
74 - }
75 - }
72 + /**
73 + * TODO: Let's re-check later to optimize it.
74 + */
75 + if ( ! betterdocs()->is_pro_active() ) {
76 + $_permalink_structure = $this->remove_knowledge_base_placeholder( $_permalink_structure );
77 + }
76 78
77 - public function permalink_structure( $structure = '', $output = 'string' ) {
78 - if ( empty( $structure ) ) {
79 - $structure = $this->settings->get( 'permalink_structure', 'docs' );
80 - }
79 + if ( $_permalink_structure !== $_old_settings['permalink_structure'] ) {
80 + $this->settings->save( 'permalink_structure', $this->permalink_structure( $_permalink_structure ) );
81 + }
81 82
82 - $docs_slug = $this->get_base_slug();
83 + $old_docs_page = isset( $_old_settings['docs_page'] ) ? $_old_settings['docs_page'] : '';
84 + $current_docs_page = isset( $_settings['docs_page'] ) ? $_settings['docs_page'] : '';
83 85
84 - $_structure_array = explode( '%', $structure );
85 - if ( $_structure_array[0] == '/' ) {
86 - $structure = $docs_slug . $structure;
87 - } else if ( $_structure_array[0] == '' ) {
88 - $structure = $docs_slug . '/' . $structure;
89 - }
86 + /**
87 + * This block of code decides whether it needs to be flushed or not.
88 + * Flush happens after register the post type.
89 + */
90 + switch ( true ) {
91 + case $_permalink_structure !== $_old_settings['permalink_structure']:
92 + case $_settings['docs_slug'] !== $_old_settings['docs_slug']:
93 + case $_settings['builtin_doc_page'] !== $_old_settings['builtin_doc_page']:
94 + case $current_docs_page !== $old_docs_page:
95 + case $_settings['tag_slug'] !== $_old_settings['tag_slug']:
96 + case $_settings['category_slug'] !== $_old_settings['category_slug']:
97 + $this->database->set_transient( 'betterdocs_flush_rewrite_rules', true );
98 + break;
99 + }
100 + }
90 101
91 - $structure = trim( $structure, '/' );
102 + public function permalink_structure( $structure = '', $output = 'string' ) {
103 + if ( empty( $structure ) ) {
104 + $structure = $this->settings->get( 'permalink_structure', 'docs' );
105 + }
92 106
93 - if ( $output === 'string' ) {
94 - return $structure;
95 - }
107 + $docs_slug = $this->get_base_slug();
96 108
97 - if ( $output === 'array' ) {
98 - $structure = explode( '/', $structure );
99 - $structure = array_map( function ( $item ) {
100 - return trim( $item, "/%" );
101 - }, $structure );
102 - }
109 + $_structure_array = explode( '%', $structure );
110 + if ( $_structure_array[0] == '/' ) {
111 + $structure = $docs_slug . $structure;
112 + } elseif ( $_structure_array[0] == '' ) {
113 + $structure = $docs_slug . '/' . $structure;
114 + }
103 115
104 - if ( $output === 'arraywithpercent' ) {
105 - $structure = explode( '/', $structure );
106 - $structure = array_map( function ( $item ) {
107 - return trim( $item, "/" );
108 - }, $structure );
109 - }
116 + $structure = trim( $structure, '/' );
110 117
111 - return $structure;
112 - }
118 + if ( $output === 'string' ) {
119 + return $structure;
120 + }
113 121
114 - public function get_base_slug() {
115 - $docs_slug = $this->settings->get( 'docs_slug', 'docs' );
116 - $docs_page = $this->settings->get( 'docs_page', 0 );
117 - $builtin_doc_page = $this->settings->get( 'builtin_doc_page', true );
122 + if ( $output === 'array' ) {
123 + $structure = explode( '/', $structure );
124 + $structure = array_map(
125 + function ( $item ) {
126 + return trim( $item, '/%' );
127 + },
128 + $structure
129 + );
130 + }
118 131
119 - if ( ! $builtin_doc_page && $docs_page !== 0 ) {
120 - $post_info = get_post( $docs_page );
121 - $docs_slug = $post_info instanceof WP_Post ? $post_info->post_name : $docs_slug;
122 - }
132 + if ( $output === 'arraywithpercent' ) {
133 + $structure = explode( '/', $structure );
134 + $structure = array_map(
135 + function ( $item ) {
136 + return trim( $item, '/' );
137 + },
138 + $structure
139 + );
140 + }
123 141
124 - $docs_slug = trim( $docs_slug, '/' );
142 + return $structure;
143 + }
125 144
126 - return $docs_slug;
127 - }
145 + public function get_base_slug() {
146 + $docs_slug = $this->settings->get( 'docs_slug', 'docs' );
147 + $docs_page = $this->settings->get( 'docs_page', 0 );
148 + $builtin_doc_page = $this->settings->get( 'builtin_doc_page', true );
128 149
129 - public function normalzie_doc_perma_structure( $structure ){
130 - $structure = $this->permalink_structure( $structure, 'arraywithpercent' );
131 - $structure = array_reduce( $structure, function( $carry, $item ){
132 - if( strpos( $item, '%' ) !== false ) {
133 - $carry[] = $item;
134 - } else {
135 - if ($carry && strpos(end($carry), '%') === false) {
136 - $carry[count($carry) - 1] .= "/$item";
137 - } else {
138 - $carry[] = $item;
139 - }
140 - }
150 + if ( ! $builtin_doc_page && $docs_page !== 0 ) {
151 + $post_info = get_post( $docs_page );
152 + $docs_slug = $post_info instanceof WP_Post ? $post_info->post_name : $docs_slug;
153 + }
141 154
142 - return $carry;
143 - }, []);
155 + $docs_slug = trim( $docs_slug, '/' );
144 156
145 - $structure[] = '%docs%';
157 + return $docs_slug;
158 + }
146 159
147 - $group = array_filter( $structure, function( $item ){
148 - return strpos($item, '%') === 0;
149 - });
160 + public function normalzie_doc_perma_structure( $structure ) {
161 + $structure = $this->permalink_structure( $structure, 'arraywithpercent' );
162 + $structure = array_reduce(
163 + $structure,
164 + function ( $carry, $item ) {
165 + if ( strpos( $item, '%' ) !== false ) {
166 + $carry[] = $item;
167 + } elseif ( $carry && strpos( end( $carry ), '%' ) === false ) {
168 + $carry[ count( $carry ) - 1 ] .= "/$item";
169 + } else {
170 + $carry[] = $item;
171 + }
150 172
151 - return [
152 - 'raw' => $structure,
153 - 'group' => $group
154 - ];
155 - }
173 + return $carry;
174 + },
175 + []
176 + );
156 177
157 - public function make_regex( $segments ){
158 - return array_reduce( $segments, function( $carry, $item ){
159 - $carry .= ( strpos( $item, '%' ) !== false ? "([^/]+)" : $item ) . '/';
160 - return $carry;
161 - }, '') . '?$';
162 - }
178 + $structure[] = '%docs%';
163 179
164 - public function make_query( $segments ){
165 - $query = [];
166 - $matchId = 1;
180 + $group = array_filter(
181 + $structure,
182 + function ( $item ) {
183 + return strpos( $item, '%' ) === 0;
184 + }
185 + );
167 186
168 - foreach( $segments as $segment ) {
169 - $query[] = trim($segment, '%') . '=$matches[' . $matchId . ']';
170 - $matchId++;
171 - }
187 + return [
188 + 'raw' => $structure,
189 + 'group' => $group
190 + ];
191 + }
172 192
173 - return 'index.php?' . implode('&', $query) . '&post_type=docs';
174 - }
193 + public function make_regex( $segments ) {
194 + return array_reduce(
195 + $segments,
196 + function ( $carry, $item ) {
197 + $carry .= ( strpos( $item, '%' ) !== false ? '([^/]+)' : $item ) . '/';
198 + return $carry;
199 + },
200 + ''
201 + ) . '?$';
202 + }
175 203
176 - public function rules() {
177 - /**
178 - * docs can be dynamic / as its a root slug
179 - *
180 - * https://url/docs/kb-slug
181 - * https://url/docs/kb-slug/category-slug
182 - * https://url/docs-category/category-slug
183 - *
184 - * Docs Visit:
185 - * docs can be dynamic / as its a root slug
186 - * or docs can be change by settings.
187 - *
188 - * https://url/docs/(docs-slug)
189 - * https://url/docs/(cat-slug)/(docs-slug)
190 - * https://url/docs/(kb-slug)/(docs-slug)
191 - * https://url/docs/(kb-slug)/(cat-slug)/(docs-slug)
192 - * https://url/docs/(cat-slug)/(kb-slug)/(docs-slug)
193 - */
204 + public function make_query( $segments ) {
205 + $query = [];
206 + $matchId = 1;
194 207
195 - /**
196 - * This code of blocks used to determine single docs permalink.
197 - */
198 - $_docs_perma_struct = betterdocs()->settings->get( 'permalink_structure', 'docs' );
199 - $_normalized_structure = $this->normalzie_doc_perma_structure($_docs_perma_struct);
208 + foreach ( $segments as $segment ) {
209 + $query[] = trim( $segment, '%' ) . '=$matches[' . $matchId . ']';
210 + ++$matchId;
211 + }
200 212
201 - $_feed_regex = $_normalized_structure['raw'];
202 - $_feed_regex[] = '(feed|rdf|rss|rss2|atom)';
203 - $_feed_group = $_normalized_structure['group'];
204 - $_feed_group[] = '%feed%';
213 + return 'index.php?' . implode( '&', $query ) . '&post_type=docs';
214 + }
205 215
206 - $this->add_rewrite_rule( $this->make_regex( $_feed_regex ), $this->make_query( $_feed_group ) );
216 + public function rules() {
217 + /**
218 + * docs can be dynamic / as its a root slug
219 + *
220 + * https://url/docs/kb-slug
221 + * https://url/docs/kb-slug/category-slug
222 + * https://url/docs-category/category-slug
223 + *
224 + * Docs Visit:
225 + * docs can be dynamic / as its a root slug
226 + * or docs can be change by settings.
227 + *
228 + * https://url/docs/(docs-slug)
229 + * https://url/docs/(cat-slug)/(docs-slug)
230 + * https://url/docs/(kb-slug)/(docs-slug)
231 + * https://url/docs/(kb-slug)/(cat-slug)/(docs-slug)
232 + * https://url/docs/(cat-slug)/(kb-slug)/(docs-slug)
233 + */
207 234
208 - $this->add_rewrite_rule(
209 - $this->make_regex( $_normalized_structure['raw'] ),
210 - $this->make_query( $_normalized_structure['group'] )
211 - );
235 + $base = $this->get_base_slug();
212 236
213 - $base = $this->get_base_slug();
214 - $this->add_rewrite_rule( $base . '/(feed|rdf|rss|rss2|atom)/?$', 'index.php?post_type=docs&feed=$matches[1]' );
215 - }
237 + // Add rule to handle pagination attempts
238 + $this->add_rewrite_rule(
239 + $base . '/page/([0-9]+)/?$',
240 + 'index.php?post_type=docs',
241 + 'top'
242 + );
216 243
217 - public function add_rewrite_rule( $regex, $query, $after = 'top' ) {
218 - add_rewrite_rule( $regex, $query, $after );
219 - }
244 + /**
245 + * This code of blocks used to determine single docs permalink.
246 + */
247 + $_docs_perma_struct = betterdocs()->settings->get( 'permalink_structure', 'docs' );
248 + $_normalized_structure = $this->normalzie_doc_perma_structure( $_docs_perma_struct );
220 249
221 - public function docs_type_rewrite( $rewrite, $slug ) {
222 - $permalink = betterdocs()->settings->get( 'permalink_structure', 'docs/' );
223 - $permalink_structure = $this->permalink_structure( $permalink, 'array' );
224 - $permalink = apply_filters( 'betterdocs_docs_type_rewrite_permalink', $permalink, $slug, $permalink_structure );
250 + $_feed_regex = $_normalized_structure['raw'];
251 + $_feed_regex[] = '(feed|rdf|rss|rss2|atom)';
252 + $_feed_group = $_normalized_structure['group'];
253 + $_feed_group[] = '%feed%';
225 254
226 - /**
227 - * TODO: Let's re-check later for optimization.
228 - */
229 - if ( ! betterdocs()->is_pro_active() ) {
230 - $permalink = $this->remove_knowledge_base_placeholder( $permalink );
231 - }
255 + $this->add_rewrite_rule( $this->make_regex( $_feed_regex ), $this->make_query( $_feed_group ) );
232 256
233 - return apply_filters( 'betterdocs_docs_rewrite', [
234 - 'slug' => trim( $permalink, '/' ),
235 - 'with_front' => false
236 - ], $slug );
237 - }
257 + $this->add_rewrite_rule(
258 + $this->make_regex( $_normalized_structure['raw'] ),
259 + $this->make_query( $_normalized_structure['group'] )
260 + );
261 +
262 + $this->add_rewrite_rule( $base . '/(feed|rdf|rss|rss2|atom)/?$', 'index.php?post_type=docs&feed=$matches[1]' );
263 + }
264 +
265 + public function add_rewrite_rule( $regex, $query, $after = 'top' ) {
266 + add_rewrite_rule( $regex, $query, $after );
267 + }
268 +
269 + public function docs_type_rewrite( $rewrite, $slug ) {
270 + $permalink = betterdocs()->settings->get( 'permalink_structure', 'docs/' );
271 + $permalink_structure = $this->permalink_structure( $permalink, 'array' );
272 + $permalink = apply_filters( 'betterdocs_docs_type_rewrite_permalink', $permalink, $slug, $permalink_structure );
273 +
274 + /**
275 + * TODO: Let's re-check later for optimization.
276 + */
277 + if ( ! betterdocs()->is_pro_active() ) {
278 + $permalink = $this->remove_knowledge_base_placeholder( $permalink );
279 + }
280 +
281 + return apply_filters(
282 + 'betterdocs_docs_rewrite',
283 + [
284 + 'slug' => trim( $permalink, '/' ),
285 + 'with_front' => false
286 + ],
287 + $slug
288 + );
289 + }
238 290 }