PluginProbe
Redirection / 5.3.1
Redirection v5.3.1
5.10.0 5.9.0 5.8.1 5.8.0 3.7.2 3.7.3 4.0 4.0.1 4.1 4.1.1 4.2 4.2.1 4.2.2 4.2.3 4.3 4.3.1 4.3.2 4.3.3 4.4 4.4.1 4.4.2 4.5 4.5.1 4.6.2 4.7.1 All 130 releases
redirection / models / permalinks.php

permalinks.php in Redirection 5.3.1, at models/permalinks.php

174 lines 3.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /**
4 * Provides permalink migration facilities
5 */
6 class Red_Permalinks {
7 /**
8 * List of migrated permalink structures
9 *
10 * @var string[]
11 */
12 private $permalinks = [];
13
14 /**
15 * Current permalink structure
16 *
17 * @var string|null
18 */
19 private $current_permalink = null;
20
21 /**
22 * Constructor
23 *
24 * @param string[] $permalinks List of migrated permalinks.
25 */
26 public function __construct( $permalinks ) {
27 $this->permalinks = $permalinks;
28 }
29
30 /**
31 * Match and migrate any permalinks
32 *
33 * @param WP_Query $query Query.
34 * @return void
35 */
36 public function migrate( WP_Query $query ) {
37 global $wp;
38
39 if ( count( $this->permalinks ) === 0 ) {
40 return;
41 }
42
43 if ( ! $this->needs_migrating() ) {
44 return;
45 }
46
47 $this->intercept_permalinks();
48
49 foreach ( $this->permalinks as $old ) {
50 // Set the current permalink
51 $this->current_permalink = $old;
52
53 // Run the WP query again
54 $wp->init();
55 $wp->parse_request();
56
57 // Anything matched?
58 if ( $wp->matched_rule ) {
59 // Perform the post query
60 $wp->query_posts();
61
62 // A single post?
63 if ( is_single() && count( $query->posts ) > 0 ) {
64 // Restore permalinks
65 $this->release_permalinks();
66
67 // Get real URL from the post ID
68 $url = get_permalink( $query->posts[0]->ID );
69 if ( $url ) {
70 wp_safe_redirect( $url, 301, 'redirection' );
71 die();
72 }
73 }
74
75 break;
76 }
77 }
78
79 $this->release_permalinks();
80 }
81
82 /**
83 * Determine if the current request needs migrating. This is based on `WP::handle_404` in class-wp.php
84 *
85 * @return boolean
86 */
87 private function needs_migrating() {
88 global $wp_query;
89
90 // It's a 404 - shortcut to yes
91 if ( is_404() ) {
92 return true;
93 }
94
95 // Not admin pages
96 if ( is_admin() || is_robots() || is_favicon() ) {
97 return false;
98 }
99
100 if ( $wp_query->posts && ! $wp_query->is_posts_page && empty( $this->query_vars['page'] ) ) {
101 return false;
102 }
103
104 if ( ! is_paged() ) {
105 $author = get_query_var( 'author' );
106
107 // Don't 404 for authors without posts as long as they matched an author on this site.
108 if ( is_author() && is_numeric( $author ) && $author > 0 && is_user_member_of_blog( $author )
109 // Don't 404 for these queries if they matched an object.
110 || ( is_tag() || is_category() || is_tax() || is_post_type_archive() ) && get_queried_object()
111 // Don't 404 for these queries either.
112 || is_home() || is_search() || is_feed()
113 ) {
114 return false;
115 }
116 }
117
118 // If we've got this far then it's a 404
119 return true;
120 }
121
122 /**
123 * Hook the permalink options and return the migrated one
124 *
125 * @return void
126 */
127 private function intercept_permalinks() {
128 add_filter( 'pre_option_rewrite_rules', [ $this, 'get_old_rewrite_rules' ] );
129 add_filter( 'pre_option_permalink_structure', [ $this, 'get_old_permalink' ] );
130 }
131
132 /**
133 * Restore the hooked option
134 *
135 * @return void
136 */
137 private function release_permalinks() {
138 remove_filter( 'pre_option_rewrite_rules', [ $this, 'get_old_rewrite_rules' ] );
139 remove_filter( 'pre_option_permalink_structure', [ $this, 'get_old_permalink' ] );
140 }
141
142 /**
143 * Returns rewrite rules for the current migrated permalink
144 *
145 * @param array $rules Current rules.
146 * @return array
147 */
148 public function get_old_rewrite_rules( $rules ) {
149 global $wp_rewrite;
150
151 if ( $this->current_permalink ) {
152 $wp_rewrite->init();
153 $wp_rewrite->matches = 'matches';
154 return $wp_rewrite->rewrite_rules();
155 }
156
157 return $rules;
158 }
159
160 /**
161 * Get the current migrated permalink structure
162 *
163 * @param string $result Current value.
164 * @return string
165 */
166 public function get_old_permalink( $result ) {
167 if ( $this->current_permalink ) {
168 return $this->current_permalink;
169 }
170
171 return $result;
172 }
173 }
174