PluginProbe ʕ •ᴥ•ʔ
Rank Math SEO – AI SEO Tools to Dominate SEO Rankings / 1.0.239
Rank Math SEO – AI SEO Tools to Dominate SEO Rankings v1.0.239
1.0.271 1.0.271.1 1.0.270 1.0.269 trunk 1.0.216 1.0.217 1.0.218 1.0.219 1.0.220 1.0.221 1.0.222 1.0.223 1.0.224 1.0.225 1.0.226 1.0.227 1.0.227.1 1.0.228 1.0.229 1.0.230 1.0.231 1.0.232 1.0.233 1.0.234 1.0.234.1 1.0.235 1.0.236 1.0.237 1.0.238 1.0.239 1.0.240 1.0.241 1.0.242 1.0.243 1.0.244 1.0.245 1.0.246 1.0.247 1.0.248 1.0.249 1.0.250 1.0.251 1.0.251.1 1.0.252 1.0.252.1 1.0.253 1.0.254 1.0.255 1.0.256 1.0.257 1.0.258 1.0.259 1.0.259.1 1.0.260 1.0.261 1.0.262 1.0.263 1.0.264 1.0.264.1 1.0.265 1.0.266 1.0.266.1 1.0.267 1.0.268
seo-by-rank-math / includes / class-rewrite.php
seo-by-rank-math / includes Last commit date
3rdparty 1 year ago admin 1 year ago cli 5 years ago frontend 1 year ago helpers 1 year ago metaboxes 2 years ago module 1 year ago modules 1 year ago opengraph 1 year ago replace-variables 1 year ago rest 1 year ago settings 1 year ago traits 1 year ago updates 1 year ago class-auto-updater.php 5 years ago class-cmb2.php 2 years ago class-common.php 1 year ago class-compatibility.php 1 year ago class-data-encryption.php 1 year ago class-defaults.php 6 years ago class-frontend-seo-score.php 1 year ago class-helper.php 1 year ago class-installer.php 1 year ago class-json-manager.php 1 year ago class-kb.php 1 year ago class-metadata.php 1 year ago class-post.php 1 year ago class-rewrite.php 2 years ago class-settings.php 1 year ago class-term.php 1 year ago class-thumbnail-overlay.php 1 year ago class-update-email.php 3 years ago class-updates.php 1 year ago class-user.php 1 year ago index.php 7 years ago interface-runner.php 7 years ago template-tags.php 1 year ago
class-rewrite.php
336 lines
1 <?php
2 /**
3 * This class handles the category and author rewrites.
4 *
5 * @since 0.9.0
6 * @package RankMath
7 * @subpackage RankMath\Core
8 * @author Rank Math <support@rankmath.com>
9 *
10 * @copyright Copyright (C) 2008-2019, Yoast BV
11 * The following code is a derivative work of the code from the Yoast(https://github.com/Yoast/wordpress-seo/), which is licensed under GPL v3.
12 */
13
14 namespace RankMath;
15
16 use RankMath\Traits\Hooker;
17 use RankMath\Helpers\Sitepress;
18
19 defined( 'ABSPATH' ) || exit;
20
21 /**
22 * Rewrite class.
23 */
24 class Rewrite {
25
26 use Hooker;
27
28 /**
29 * The Constructor.
30 */
31 public function __construct() {
32
33 if ( Helper::get_settings( 'general.strip_category_base' ) ) {
34 $this->filter( 'query_vars', 'query_vars' );
35 $this->filter( 'request', 'request' );
36 $this->filter( 'category_rewrite_rules', 'category_rewrite_rules' );
37 $this->filter( 'term_link', 'no_category_base', 10, 3 );
38
39 add_action( 'created_category', 'RankMath\\Helper::schedule_flush_rewrite' );
40 add_action( 'delete_category', 'RankMath\\Helper::schedule_flush_rewrite' );
41 add_action( 'edited_category', 'RankMath\\Helper::schedule_flush_rewrite' );
42 }
43
44 if ( ! Helper::get_settings( 'titles.disable_author_archives' ) ) {
45 if ( ! empty( Helper::get_settings( 'titles.url_author_base' ) ) ) {
46 add_action( 'init', 'RankMath\\Rewrite::change_author_base', 4 );
47 }
48
49 $this->filter( 'author_link', 'author_link', 10, 3 );
50 $this->filter( 'request', 'author_request' );
51 }
52 }
53
54 /**
55 * Change the URL to the author's page.
56 *
57 * @param string $link The URL to the author's page.
58 * @param int $author_id The author's ID.
59 * @param string $author_nicename The author's nice name.
60 * @return string
61 */
62 public function author_link( $link, $author_id, $author_nicename ) {
63 $custom_url = get_user_meta( $author_id, 'rank_math_permalink', true );
64 if ( $custom_url ) {
65 $link = str_replace( $author_nicename, $custom_url, $link );
66 }
67
68 return $link;
69 }
70
71 /**
72 * Redirect the old user permalink to the new one.
73 *
74 * @param array $query_vars Query vars to check for author_name var.
75 *
76 * @return array
77 */
78 public function author_request( $query_vars ) {
79 global $wpdb;
80
81 if ( ! array_key_exists( 'author_name', $query_vars ) ) {
82 return $query_vars;
83 }
84
85 $author_id = $wpdb->get_var( $wpdb->prepare( "SELECT user_id FROM {$wpdb->usermeta} WHERE meta_key='rank_math_permalink' AND meta_value = %s", $query_vars['author_name'] ) );
86 if ( $author_id ) {
87 $query_vars['author'] = $author_id;
88 unset( $query_vars['author_name'] );
89 }
90
91 return $query_vars;
92 }
93
94 /**
95 * Remove the rewrite rules.
96 */
97 public function remove_rules() {
98 $this->remove_filter( 'query_vars', 'query_vars' );
99 $this->remove_filter( 'request', 'request' );
100 $this->remove_filter( 'category_rewrite_rules', 'category_rewrite_rules' );
101 $this->remove_filter( 'term_link', 'no_category_base', 10 );
102
103 remove_action( 'init', 'RankMath\\Rewrite::change_author_base', 4 );
104 }
105
106 /**
107 * Change the base for author permalinks.
108 */
109 public static function change_author_base() {
110 global $wp_rewrite;
111
112 /**
113 * Filter: Change the author base.
114 *
115 * @param string $base The author base.
116 */
117 $base = apply_filters( 'rank_math/author_base', sanitize_title_with_dashes( Helper::get_settings( 'titles.url_author_base' ), '', 'save' ) );
118 if ( empty( $base ) ) {
119 return;
120 }
121
122 $wp_rewrite->author_base = $base;
123 $wp_rewrite->author_structure = '/' . $wp_rewrite->author_base . '/%author%';
124 }
125
126 /**
127 * Add the redirect var to the query vars if the "strip category bases" option is enabled.
128 *
129 * @param array $query_vars Query vars to filter.
130 *
131 * @return array
132 */
133 public function query_vars( $query_vars ) {
134 $query_vars[] = 'rank_math_category_redirect';
135
136 return $query_vars;
137 }
138
139 /**
140 * Redirect the original category URL to the new one.
141 *
142 * @param array $query_vars Query vars to check for redirect var.
143 * @return array
144 */
145 public function request( $query_vars ) {
146 if ( isset( $query_vars['rank_math_category_redirect'] ) ) {
147 $catlink = trailingslashit( get_option( 'home' ) ) . user_trailingslashit( $query_vars['rank_math_category_redirect'], 'category' );
148 Helper::redirect( $catlink, 301 );
149 exit;
150 }
151
152 return $query_vars;
153 }
154
155 /**
156 * This function was taken and slightly adapted from WP No Category Base plugin by Saurabh Gupta.
157 *
158 * @return array
159 */
160 public function category_rewrite_rules() {
161 global $wp_rewrite;
162
163 $category_rewrite = $this->get_category_rules();
164
165 $old_base = str_replace( '%category%', '(.+)', $wp_rewrite->get_category_permastruct() );
166 $old_base = trim( $old_base, '/' );
167 $category_rewrite[ $old_base . '$' ] = 'index.php?rank_math_category_redirect=$matches[1]';
168
169 return $category_rewrite;
170 }
171
172 /**
173 * Remove the category base from the category link.
174 *
175 * @param string $link Term link.
176 * @param object $term Current Term Object.
177 * @param string $taxonomy Current Taxonomy.
178 * @return string
179 */
180 public function no_category_base( $link, $term, $taxonomy ) {
181 if ( 'category' !== $taxonomy ) {
182 return $link;
183 }
184
185 $category_base = get_option( 'category_base' );
186 if ( empty( $category_base ) ) {
187 global $wp_rewrite;
188 $category_base = trim( str_replace( '%category%', '', $wp_rewrite->get_category_permastruct() ), '/' );
189 }
190
191 // Remove initial slash, if there is one (we remove the trailing slash in the regex replacement and don't want to end up short a slash).
192 if ( '/' === substr( $category_base, 0, 1 ) ) {
193 $category_base = substr( $category_base, 1 );
194 }
195
196 $category_base .= '/';
197
198 return preg_replace( '`' . preg_quote( $category_base, '`' ) . '`u', '', $link, 1 );
199 }
200 /**
201 * Get category re-write rules.
202 *
203 * @return array
204 */
205 private function get_category_rules() {
206 global $wp_rewrite;
207
208 $category_rewrite = [];
209 $categories = $this->get_categories();
210 $blog_prefix = $this->get_blog_prefix();
211
212 if ( empty( $categories ) ) {
213 return $category_rewrite;
214 }
215
216 foreach ( $categories as $category ) {
217 $category_nicename = $this->get_category_parents( $category ) . $category->slug;
218 $category_rewrite = $this->add_category_rewrites( $category_rewrite, $category_nicename, $blog_prefix, $wp_rewrite->pagination_base );
219
220 // Add rules for upper case encoded nicename.
221 $category_nicename_filtered = $this->convert_encoded_to_upper( $category_nicename );
222
223 if ( $category_nicename !== $category_nicename_filtered ) {
224 $category_rewrite = $this->add_category_rewrites( $category_rewrite, $category_nicename_filtered, $blog_prefix, $wp_rewrite->pagination_base );
225 }
226 }
227
228 return $category_rewrite;
229 }
230
231 /**
232 * Adds required category rewrites rules.
233 *
234 * @param array $category_rewrite The current set of rules.
235 * @param string $category_nicename Category nicename.
236 * @param string $blog_prefix Multisite blog prefix.
237 * @param string $pagination_base WP_Query pagination base.
238 *
239 * @return array The added set of rules.
240 */
241 private function add_category_rewrites( $category_rewrite, $category_nicename, $blog_prefix, $pagination_base ) {
242
243 $category_rewrite[ $blog_prefix . '(' . $category_nicename . ')/(?:feed/)?(feed|rdf|rss|rss2|atom)/?$' ] = 'index.php?category_name=$matches[1]&feed=$matches[2]';
244 $category_rewrite[ $blog_prefix . '(' . $category_nicename . ')/' . $pagination_base . '/?([0-9]{1,})/?$' ] = 'index.php?category_name=$matches[1]&paged=$matches[2]';
245 $category_rewrite[ $blog_prefix . '(' . $category_nicename . ')/?$' ] = 'index.php?category_name=$matches[1]';
246
247 return $category_rewrite;
248 }
249
250 /**
251 * Walks through category nicename and convert encoded parts
252 * into uppercase using $this->encode_to_upper().
253 *
254 * @param string $name The encoded category URI string.
255 *
256 * @return string The convered URI string.
257 */
258 private function convert_encoded_to_upper( $name ) {
259 // Checks if name has any encoding in it.
260 if ( strpos( $name, '%' ) === false ) {
261 return $name;
262 }
263
264 $names = explode( '/', $name );
265 $names = array_map( [ $this, 'encode_to_upper' ], $names );
266
267 return implode( '/', $names );
268 }
269
270 /**
271 * Converts the encoded URI string to uppercase.
272 *
273 * @param string $encoded The encoded string.
274 *
275 * @return string The uppercased string.
276 */
277 private function encode_to_upper( $encoded ) {
278 if ( strpos( $encoded, '%' ) === false ) {
279 return $encoded;
280 }
281
282 return strtoupper( $encoded );
283 }
284
285 /**
286 * Retrieve category parents with separator.
287 *
288 * @param WP_Term $category Category instance.
289 *
290 * @return string
291 */
292 private function get_category_parents( $category ) {
293 if ( $category->parent === $category->cat_ID || absint( $category->parent ) < 1 ) {
294 return '';
295 }
296
297 $parents = get_category_parents( $category->parent, false, '/', true );
298 return is_wp_error( $parents ) ? '' : $parents;
299 }
300
301 /**
302 * Get categories with WPML compatibility.
303 *
304 * @return array
305 */
306 private function get_categories() {
307 /**
308 * Remove WPML filters while getting terms, to get all languages
309 */
310 Sitepress::get()->remove_term_filters();
311
312 $categories = get_categories( [ 'hide_empty' => false ] );
313
314 /**
315 * Register WPML filters back
316 */
317 Sitepress::get()->restore_term_filters();
318
319 return $categories;
320 }
321
322 /**
323 * Get the blog prefix.
324 *
325 * @return string
326 */
327 private function get_blog_prefix() {
328 $permalink_structure = get_option( 'permalink_structure' );
329 if ( is_multisite() && ! is_subdomain_install() && is_main_site() && 0 === strpos( $permalink_structure, '/blog/' ) ) {
330 return 'blog/';
331 }
332
333 return '';
334 }
335 }
336