PluginProbe
Redirection / 5.2
Redirection v5.2
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
← All changes | redirection-admin.php +239 -86 4.05.2 View file →
@@ -1,10 +1,11 @@
1 1 <?php
2 2
3 -include_once dirname( __FILE__ ) . '/models/group.php';
4 -include_once dirname( __FILE__ ) . '/models/monitor.php';
5 -include_once dirname( __FILE__ ) . '/models/file-io.php';
6 -include_once dirname( __FILE__ ) . '/database/database.php';
3 +require_once __DIR__ . '/models/group.php';
4 +require_once __DIR__ . '/models/monitor.php';
5 +require_once __DIR__ . '/models/file-io.php';
6 +require_once __DIR__ . '/database/database.php';
7 +require_once __DIR__ . '/redirection-capabilities.php';
7 8
8 9 define( 'RED_DEFAULT_PER_PAGE', 25 );
9 10 define( 'RED_MAX_PER_PAGE', 200 );
10 11
@@ -12,9 +13,9 @@
12 13 private static $instance = null;
13 14 private $monitor;
14 15 private $fixit_failed = false;
15 16
16 - static function init() {
17 + public static function init() {
17 18 if ( is_null( self::$instance ) ) {
18 19 self::$instance = new Redirection_Admin();
19 20 }
20 21
@@ -20,23 +21,27 @@
20 21
21 22 return self::$instance;
22 23 }
23 24
24 - function __construct() {
25 - add_action( 'admin_menu', array( $this, 'admin_menu' ) );
26 - add_action( 'admin_notices', array( $this, 'update_nag' ) );
27 - add_action( 'plugin_action_links_' . basename( dirname( REDIRECTION_FILE ) ) . '/' . basename( REDIRECTION_FILE ), array( $this, 'plugin_settings' ), 10, 4 );
28 - add_filter( 'plugin_row_meta', array( $this, 'plugin_row_meta' ), 10, 4 );
29 - add_filter( 'redirection_save_options', array( $this, 'flush_schedule' ) );
30 - add_filter( 'set-screen-option', array( $this, 'set_per_page' ), 10, 3 );
31 - add_action( 'redirection_redirect_updated', array( $this, 'set_default_group' ), 10, 2 );
25 + public function __construct() {
26 + add_action( 'admin_menu', [ $this, 'admin_menu' ] );
27 + add_action( 'admin_notices', [ $this, 'update_nag' ] );
28 + add_filter( 'plugin_action_links_' . basename( dirname( REDIRECTION_FILE ) ) . '/' . basename( REDIRECTION_FILE ), [ $this, 'plugin_settings' ], 10, 4 );
29 + add_filter( 'plugin_row_meta', [ $this, 'plugin_row_meta' ], 10, 4 );
30 + add_filter( 'redirection_save_options', [ $this, 'flush_schedule' ] );
31 + add_filter( 'set-screen-option', [ $this, 'set_per_page' ], 10, 3 );
32 + add_filter( 'set_screen_option_redirection_log_per_page', function( $ignore, $option, $value ) {
33 + return $value;
34 + }, 10, 3 );
35 + add_action( 'redirection_redirect_updated', [ $this, 'set_default_group' ], 10, 2 );
36 + add_action( 'redirection_redirect_updated', [ $this, 'clear_cache' ], 10, 2 );
32 37
33 38 if ( defined( 'REDIRECTION_FLYING_SOLO' ) && REDIRECTION_FLYING_SOLO ) {
34 - add_filter( 'script_loader_src', array( $this, 'flying_solo' ), 10, 2 );
39 + add_filter( 'script_loader_src', [ $this, 'flying_solo' ], 10, 2 );
35 40 }
36 41
37 - register_deactivation_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_deactivated' ) );
38 - register_uninstall_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_uninstall' ) );
42 + register_deactivation_hook( REDIRECTION_FILE, [ 'Redirection_Admin', 'plugin_deactivated' ] );
43 + register_uninstall_hook( REDIRECTION_FILE, [ 'Redirection_Admin', 'plugin_uninstall' ] );
39 44
40 45 $this->monitor = new Red_Monitor( red_get_options() );
41 46 $this->run_hacks();
42 47 }
@@ -64,18 +69,37 @@
64 69 $database->remove();
65 70 } );
66 71 }
67 72
73 + /**
74 + * Show the database upgrade nag
75 + *
76 + * @return void
77 + */
68 78 public function update_nag() {
79 + $options = red_get_options();
80 +
81 + // Is the site configured to upgrade automatically?
82 + if ( $options['plugin_update'] === 'admin' ) {
83 + $this->automatic_upgrade();
84 + return;
85 + }
86 +
87 + // Can the user perform a manual database upgrade?
88 + if ( ! Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_OPTION_MANAGE ) ) {
89 + return;
90 + }
91 +
92 + // Default manual update, with nag
69 93 $status = new Red_Database_Status();
70 94
71 95 $message = false;
72 96 if ( $status->needs_installing() ) {
73 97 /* translators: 1: URL to plugin page */
74 - $message = sprintf( __( 'Please complete your <a href="%s">Redirection setup</a> to activate the plugin.' ), 'tools.php?page=' . basename( REDIRECTION_FILE ) );
98 + $message = sprintf( __( 'Please complete your <a href="%s">Redirection setup</a> to activate the plugin.', 'redirection' ), esc_url( $this->get_plugin_url() ) );
75 99 } elseif ( $status->needs_updating() ) {
76 100 /* translators: 1: URL to plugin page, 2: current version, 3: target version */
77 - $message = sprintf( __( 'Redirection\'s database needs to be updated - <a href="%1$1s">click to update</a>.' ), 'tools.php?page=' . basename( REDIRECTION_FILE ) );
101 + $message = sprintf( __( 'Redirection\'s database needs to be updated - <a href="%1$1s">click to update</a>.', 'redirection' ), esc_url( $this->get_plugin_url() ) );
78 102 }
79 103
80 104 if ( ! $message || strpos( Redirection_Request::get_request_url(), 'page=redirection.php' ) !== false ) {
81 105 return;
@@ -80,12 +104,41 @@
80 104 if ( ! $message || strpos( Redirection_Request::get_request_url(), 'page=redirection.php' ) !== false ) {
81 105 return;
82 106 }
83 107
84 - // Contains HTML
85 - echo '<div class="update-nag">' . $message . '</div>';
108 + // Known HTML and so isn't escaped
109 + // phpcs:ignore
110 + echo '<div class="update-nag notice notice-warning" style="width: 95%">' . $message . '</div>';
86 111 }
87 112
113 + /**
114 + * Perform an automatic DB upgrade
115 + *
116 + * @return void
117 + */
118 + private function automatic_upgrade() {
119 + $loop = 0;
120 + $status = new Red_Database_Status();
121 + $database = new Red_Database();
122 +
123 + // Loop until the DB is upgraded, or until a max is exceeded (just in case)
124 + while ( $loop < 20 ) {
125 + if ( ! $status->needs_updating() ) {
126 + break;
127 + }
128 +
129 + $database->apply_upgrade( $status );
130 +
131 + if ( $status->is_error() ) {
132 + // If an error occurs then switch to 'prompt' mode and let the user deal with it.
133 + red_set_options( [ 'plugin_update' => 'prompt' ] );
134 + return;
135 + }
136 +
137 + $loop++;
138 + }
139 + }
140 +
88 141 // So it finally came to this... some plugins include their JS in all pages, whether they are needed or not. If there is an error
89 142 // then this can prevent Redirection running and it's a little sensitive about that. We use the nuclear option here to disable
90 143 // all other JS while viewing Redirection
91 144 public function flying_solo( $src, $handle ) {
@@ -122,27 +175,28 @@
122 175 Red_Flusher::schedule();
123 176 return $options;
124 177 }
125 178
126 - function set_per_page( $status, $option, $value ) {
179 + public function set_per_page( $status, $option, $value ) {
127 180 if ( $option === 'redirection_log_per_page' ) {
128 - return max( 1, min( intval( $value, 10 ), RED_MAX_PER_PAGE ) );
181 + $value = max( 1, min( intval( $value, 10 ), RED_MAX_PER_PAGE ) );
182 + return $value;
129 183 }
130 184
131 185 return $status;
132 186 }
133 187
134 - function plugin_settings( $links ) {
188 + public function plugin_settings( $links ) {
135 189 $status = new Red_Database_Status();
136 190 if ( $status->needs_updating() ) {
137 - array_unshift( $links, '<a style="color: red" href="tools.php?page=' . basename( REDIRECTION_FILE ) . '&amp;sub=support">' . __( 'Upgrade Database', 'redirection' ) . '</a>' );
191 + array_unshift( $links, '<a style="color: red" href="' . esc_url( $this->get_plugin_url() ) . '&amp;sub=support">' . __( 'Upgrade Database', 'redirection' ) . '</a>' );
138 192 }
139 193
140 - array_unshift( $links, '<a href="tools.php?page=' . basename( REDIRECTION_FILE ) . '&amp;sub=options">' . __( 'Settings', 'redirection' ) . '</a>' );
194 + array_unshift( $links, '<a href="' . esc_url( $this->get_plugin_url() ) . '&amp;sub=options">' . __( 'Settings', 'redirection' ) . '</a>' );
141 195 return $links;
142 196 }
143 197
144 - function plugin_row_meta( $plugin_meta, $plugin_file, $plugin_data, $status ) {
198 + public function plugin_row_meta( $plugin_meta, $plugin_file, $plugin_data, $status ) {
145 199 if ( $plugin_file === basename( dirname( REDIRECTION_FILE ) ) . '/' . basename( REDIRECTION_FILE ) ) {
146 200 $plugin_data['Description'] .= '<p>' . __( 'Please upgrade your database', 'redirection' ) . '</p>';
147 201 }
148 202
@@ -148,12 +202,31 @@
148 202
149 203 return $plugin_meta;
150 204 }
151 205
152 - function redirection_head() {
206 + private function get_plugin_url() {
207 + return admin_url( 'tools.php?page=' . basename( REDIRECTION_FILE ) );
208 + }
209 +
210 + private function get_first_available_page_url() {
211 + $pages = Redirection_Capabilities::get_available_pages();
212 +
213 + if ( count( $pages ) > 0 ) {
214 + return $this->get_plugin_url() . ( $pages[0] === 'redirect' ? '' : '&sub=' . rawurlencode( $pages[0] ) );
215 + }
216 +
217 + return admin_url();
218 + }
219 +
220 + public function redirection_head() {
153 221 global $wp_version;
154 222
155 - $this->check_rest_api();
223 + // Does user have access to this page?
224 + if ( $this->get_current_page() === false ) {
225 + // Redirect to root plugin page
226 + wp_safe_redirect( $this->get_first_available_page_url() );
227 + die();
228 + }
156 229
157 230 if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( $_REQUEST['_wpnonce'], 'wp_rest' ) ) {
158 231 if ( $_REQUEST['action'] === 'fixit' ) {
159 232 $this->run_fixit();
@@ -165,19 +238,20 @@
165 238 $build = REDIRECTION_VERSION . '-' . REDIRECTION_BUILD;
166 239 $preload = $this->get_preload_data();
167 240 $options = red_get_options();
168 241 $versions = array(
169 - 'Plugin: ' . REDIRECTION_VERSION,
242 + 'Plugin: ' . REDIRECTION_VERSION . ' ' . REDIRECTION_DB_VERSION,
170 243 'WordPress: ' . $wp_version . ' (' . ( is_multisite() ? 'multi' : 'single' ) . ')',
171 244 'PHP: ' . phpversion(),
172 245 'Browser: ' . Redirection_Request::get_user_agent(),
173 - 'JavaScript: ' . plugin_dir_url( REDIRECTION_FILE ) . 'redirection.js',
246 + 'JavaScript: ' . plugin_dir_url( REDIRECTION_FILE ) . 'redirection.js?ver=' . $build,
174 247 'REST API: ' . red_get_rest_api(),
175 248 );
176 249
177 250 $this->inject();
178 251
179 - if ( in_array( $this->get_menu_page(), array( 'redirects', 'log', '404s', 'groups' ) ) ) {
252 + // Add contextual help to some pages
253 + if ( in_array( $this->get_current_page(), [ 'redirect', 'log', '404s', 'groups' ], true ) ) {
180 254 add_screen_option( 'per_page', array(
181 255 /* translators: maximum number of log entries */
182 256 'label' => sprintf( __( 'Log entries (%d max)', 'redirection' ), RED_MAX_PER_PAGE ),
183 257 'default' => RED_DEFAULT_PER_PAGE,
@@ -192,24 +266,51 @@
192 266 }
193 267
194 268 wp_enqueue_style( 'redirection', plugin_dir_url( REDIRECTION_FILE ) . 'redirection.css', array(), $build );
195 269
270 + $is_new = false;
271 + $major_version = implode( '.', array_slice( explode( '.', REDIRECTION_VERSION ), 0, 2 ) );
272 +
273 + // phpcs:ignore
274 + if ( isset( $_GET['page'] ) && $_GET['page'] === 'redirection.php' && strpos( REDIRECTION_VERSION, '-beta' ) === false ) {
275 + $is_new = version_compare( $options['update_notice'], $major_version ) < 0;
276 + }
277 +
196 278 $status = new Red_Database_Status();
197 279 $status->check_tables_exist();
198 280
281 + $translations = $this->get_i18n_data();
282 +
199 283 wp_localize_script( 'redirection', 'Redirectioni10n', array(
200 - 'WP_API_root' => esc_url_raw( red_get_rest_api() ),
201 - 'WP_API_nonce' => wp_create_nonce( 'wp_rest' ),
284 + 'api' => [
285 + 'WP_API_root' => esc_url_raw( red_get_rest_api() ),
286 + 'WP_API_nonce' => wp_create_nonce( 'wp_rest' ),
287 + 'site_health' => admin_url( 'site-health.php' ),
288 + 'current' => $options['rest_api'],
289 + 'routes' => [
290 + REDIRECTION_API_JSON => red_get_rest_api( REDIRECTION_API_JSON ),
291 + REDIRECTION_API_JSON_INDEX => red_get_rest_api( REDIRECTION_API_JSON_INDEX ),
292 + REDIRECTION_API_JSON_RELATIVE => red_get_rest_api( REDIRECTION_API_JSON_RELATIVE ),
293 + ],
294 + ],
202 295 'pluginBaseUrl' => plugins_url( '', REDIRECTION_FILE ),
203 - 'pluginRoot' => admin_url( 'tools.php?page=redirection.php' ),
296 + 'pluginRoot' => $this->get_plugin_url(),
204 297 'per_page' => $this->get_per_page(),
205 - 'locale' => $this->get_i18n_data(),
206 - 'localeSlug' => get_locale(),
298 + 'locale' => [
299 + 'translations' => $translations,
300 + 'localeSlug' => get_locale(),
301 + 'Plural-Forms' => isset( $translations['plural-forms'] ) ? $translations['plural-forms'] : 'nplurals=2; plural=n != 1;',
302 + ],
207 303 'settings' => $options,
208 304 'preload' => $preload,
209 305 'versions' => implode( "\n", $versions ),
210 306 'version' => REDIRECTION_VERSION,
211 307 'database' => $status->get_json(),
308 + 'caps' => [
309 + 'pages' => Redirection_Capabilities::get_available_pages(),
310 + 'capabilities' => Redirection_Capabilities::get_all_capabilities(),
311 + ],
312 + 'update_notice' => $is_new ? $major_version : false,
212 313 ) );
213 314
214 315 $this->add_help_tab();
215 316 }
@@ -218,9 +319,9 @@
218 319 private function run_hacks() {
219 320 add_filter( 'ip-geo-block-admin', array( $this, 'ip_geo_block' ) );
220 321 }
221 322
222 - /**
323 + /*
223 324 * This works around the IP Geo Block plugin being very aggressive and breaking Redirection
224 325 */
225 326 public function ip_geo_block( $validate ) {
226 327 $url = Redirection_Request::get_request_url();
@@ -243,28 +344,11 @@
243 344
244 345 return $validate;
245 346 }
246 347
247 - public function check_rest_api() {
248 - $options = red_get_options();
249 -
250 - if ( $options['rest_api'] === false || ( defined( 'REDIRECTION_FORCE_UPDATE' ) && REDIRECTION_FORCE_UPDATE ) ) {
251 - include_once dirname( REDIRECTION_FILE ) . '/models/fixer.php';
252 -
253 - $fixer = new Red_Fixer();
254 - $status = $fixer->get_rest_status();
255 -
256 - if ( $status['status'] === 'problem' ) {
257 - $fixer->fix_rest();
258 - } elseif ( $options['rest_api'] === false ) {
259 - red_set_options( array( 'rest_api' => 0 ) );
260 - }
261 - }
262 - }
263 -
264 348 private function run_fixit() {
265 - if ( current_user_can( apply_filters( 'redirection_role', 'manage_options' ) ) ) {
266 - include_once dirname( REDIRECTION_FILE ) . '/models/fixer.php';
349 + if ( Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_SUPPORT_MANAGE ) ) {
350 + require_once dirname( REDIRECTION_FILE ) . '/models/fixer.php';
267 351
268 352 $fixer = new Red_Fixer();
269 353 $result = $fixer->fix( $fixer->get_status() );
270 354
@@ -274,23 +358,35 @@
274 358 }
275 359 }
276 360
277 361 private function set_rest_api( $api ) {
278 - if ( $api >= 0 && $api <= REDIRECTION_API_POST ) {
362 + if ( $api >= 0 && $api <= REDIRECTION_API_JSON_RELATIVE ) {
279 363 red_set_options( array( 'rest_api' => intval( $api, 10 ) ) );
280 364 }
281 365 }
282 366
283 367 private function get_preload_data() {
284 - if ( $this->get_menu_page() === 'support' ) {
285 - $api = new Redirection_Api_Plugin( REDIRECTION_API_NAMESPACE );
368 + $status = new Red_Database_Status();
286 369
370 + if ( $status->needs_installing() ) {
371 + include_once __DIR__ . '/models/importer.php';
372 +
373 + return [
374 + 'importers' => Red_Plugin_Importer::get_plugins(),
375 + ];
376 + }
377 +
378 + if ( $this->get_current_page() === 'support' ) {
379 + require_once dirname( REDIRECTION_FILE ) . '/models/fixer.php';
380 +
381 + $fixer = new Red_Fixer();
382 +
287 383 return array(
288 - 'pluginStatus' => $api->route_status( new WP_REST_Request() ),
384 + 'pluginStatus' => $fixer->get_json(),
289 385 );
290 386 }
291 387
292 - return array();
388 + return [];
293 389 }
294 390
295 391 private function add_help_tab() {
296 392 /* translators: URL */
@@ -321,12 +417,13 @@
321 417
322 418 $i18n_json = dirname( REDIRECTION_FILE ) . '/locale/json/redirection-' . $locale . '.json';
323 419
324 420 if ( is_file( $i18n_json ) && is_readable( $i18n_json ) ) {
421 + // phpcs:ignore
325 422 $locale_data = @file_get_contents( $i18n_json );
326 423
327 424 if ( $locale_data ) {
328 - return json_decode( $locale_data );
425 + return json_decode( $locale_data, true );
329 426 }
330 427 }
331 428
332 429 // Return empty if we have nothing to return so it doesn't fail when parsed in JS
@@ -332,11 +429,11 @@
332 429 // Return empty if we have nothing to return so it doesn't fail when parsed in JS
333 430 return array();
334 431 }
335 432
336 - function admin_menu() {
337 - $hook = add_management_page( 'Redirection', 'Redirection', apply_filters( 'redirection_role', 'manage_options' ), basename( REDIRECTION_FILE ), array( &$this, 'admin_screen' ) );
338 - add_action( 'load-' . $hook, array( $this, 'redirection_head' ) );
433 + public function admin_menu() {
434 + $hook = add_management_page( 'Redirection', 'Redirection', Redirection_Capabilities::get_plugin_access(), basename( REDIRECTION_FILE ), [ $this, 'admin_screen' ] );
435 + add_action( 'load-' . $hook, [ $this, 'redirection_head' ] );
339 436 }
340 437
341 438 private function check_minimum_wp() {
342 439 $wp_version = get_bloginfo( 'version' );
@@ -347,13 +444,30 @@
347 444
348 445 return true;
349 446 }
350 447
448 + /**
449 + * Update the cache key when updating or creating a redirect
450 + *
451 + * @return void
452 + */
453 + public function clear_cache() {
454 + $settings = red_get_options();
455 +
456 + if ( $settings['cache_key'] > 0 ) {
457 + red_set_options( [ 'cache_key' => time() ] );
458 + }
459 + }
460 +
351 461 public function set_default_group( $id, $redirect ) {
352 462 red_set_options( array( 'last_group_id' => $redirect->get_group_id() ) );
353 463 }
354 464
355 465 public function admin_screen() {
466 + if ( count( Redirection_Capabilities::get_all_capabilities() ) === 0 ) {
467 + die( 'You do not have sufficient permissions to access this page.' );
468 + }
469 +
356 470 if ( $this->check_minimum_wp() === false ) {
357 471 return $this->show_minimum_wordpress();
358 472 }
359 473
@@ -375,8 +489,10 @@
375 489 <?php
376 490 }
377 491
378 492 private function show_minimum_wordpress() {
493 + global $wp_version;
494 +
379 495 /* translators: 1: Expected WordPress version, 2: Actual WordPress version */
380 496 $wp_requirement = sprintf( __( 'Redirection requires WordPress v%1$1s, you are using v%2$2s - please update your WordPress', 'redirection' ), REDIRECTION_MIN_WP, $wp_version );
381 497 ?>
382 498 <div class="react-error">
@@ -392,9 +508,9 @@
392 508 <h1><?php esc_html_e( 'Unable to load Redirection ☹️', 'redirection' ); ?> v<?php echo esc_html( REDIRECTION_VERSION ); ?></h1>
393 509 <p><?php esc_html_e( "This may be caused by another plugin - look at your browser's error console for more details.", 'redirection' ); ?></p>
394 510 <p><?php esc_html_e( 'If you are using a page caching plugin or service (CloudFlare, OVH, etc) then you can also try clearing that cache.', 'redirection' ); ?></p>
395 511 <p><?php _e( 'Also check if your browser is able to load <code>redirection.js</code>:', 'redirection' ); ?></p>
396 - <p><code><?php echo esc_html( plugin_dir_url( REDIRECTION_FILE ) . 'redirection.js?ver=' . urlencode( REDIRECTION_VERSION ) . '-' . urlencode( REDIRECTION_BUILD ) ); ?></code></p>
512 + <p><code><?php echo esc_html( plugin_dir_url( REDIRECTION_FILE ) . 'redirection.js?ver=' . rawurlencode( REDIRECTION_VERSION ) . '-' . rawurlencode( REDIRECTION_BUILD ) ); ?></code></p>
397 513 <p><?php esc_html_e( 'Please note that Redirection requires the WordPress REST API to be enabled. If you have disabled this then you won\'t be able to use Redirection', 'redirection' ); ?></p>
398 514 <p><?php _e( 'Please see the <a href="https://redirection.me/support/problems/">list of common problems</a>.', 'redirection' ); ?></p>
399 515 <p><?php esc_html_e( 'If you think Redirection is at fault then create an issue.', 'redirection' ); ?></p>
400 516 <p class="versions"><?php _e( '<code>Redirectioni10n</code> is not defined. This usually means another plugin is blocking Redirection from loading. Please disable all plugins and try again.', 'redirection' ); ?></p>
@@ -447,9 +563,9 @@
447 563 resetAll();
448 564 document.querySelector( '.react-loading' ).style.display = 'none';
449 565 document.querySelector( '.react-error' ).style.display = 'block';
450 566
451 - if ( typeof Redirectioni10n !== 'undefined' ) {
567 + if ( typeof Redirectioni10n !== 'undefined' && Redirectioni10n ) {
452 568 document.querySelector( '.versions' ).innerHTML = Redirectioni10n.versions.replace( /\n/g, '<br />' );
453 569 document.querySelector( '.react-error .button-primary' ).href += '&body=' + encodeURIComponent( errorText ) + encodeURIComponent( Redirectioni10n.versions );
454 570 }
455 571 }
@@ -466,14 +582,36 @@
466 582 </script>
467 583 <?php
468 584 }
469 585
470 - private function user_has_access() {
471 - return current_user_can( apply_filters( 'redirection_role', 'manage_options' ) );
586 + /**
587 + * Get the current plugin page.
588 + * Uses $_GET['sub'] to determine the current page unless a page is supplied.
589 + *
590 + * @param string $page Current page.
591 + *
592 + * @return string|boolean Current page, or false.
593 + */
594 + private function get_current_page( $page = false ) {
595 + // $_GET['sub'] is validated below
596 + // phpcs:ignore
597 + if ( ! $page ) {
598 + // phpcs:ignore
599 + $page = isset( $_GET['sub'] ) ? $_GET['sub'] : 'redirect';
600 + }
601 +
602 + // Are we allowed to access this page?
603 + if ( in_array( $page, Redirection_Capabilities::get_available_pages(), true ) ) {
604 + // phpcs:ignore
605 + return $page;
606 + }
607 +
608 + return false;
472 609 }
473 610
474 611 private function inject() {
475 - if ( isset( $_GET['page'] ) && $this->get_menu_page() !== 'redirects' && $_GET['page'] === 'redirection.php' ) {
612 + // phpcs:ignore
613 + if ( isset( $_GET['page'] ) && $this->get_current_page() !== 'redirect' && $_GET['page'] === 'redirection.php' ) {
476 614 $this->try_export_logs();
477 615 $this->try_export_redirects();
478 616 $this->try_export_rss();
479 617 }
@@ -478,25 +616,22 @@
478 616 $this->try_export_rss();
479 617 }
480 618 }
481 619
482 - private function get_menu_page() {
483 - if ( isset( $_GET['sub'] ) && in_array( $_GET['sub'], array( 'group', '404s', 'log', 'io', 'options', 'support', true ) ) ) {
484 - return $_GET['sub'];
485 - }
486 -
487 - return 'redirects';
488 - }
489 -
490 620 public function try_export_rss() {
491 - if ( isset( $_GET['token'] ) && $this->get_menu_page() === 'rss' ) {
621 + // phpcs:ignore
622 + if ( isset( $_GET['token'] ) && isset( $_GET['sub'] ) && $_GET['sub'] === 'rss' && Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_REDIRECT_MANAGE ) ) {
492 623 $options = red_get_options();
493 624
625 + // phpcs:ignore
494 626 if ( $_GET['token'] === $options['token'] && ! empty( $options['token'] ) ) {
495 - $items = Red_Item::get_all_for_module( intval( $_GET['module'] ) );
627 + // phpcs:ignore
628 + $items = Red_Item::get_all_for_module( intval( $_GET['module'], 10 ) );
496 629
497 630 $exporter = Red_FileIO::create( 'rss' );
498 631 $exporter->force_download();
632 +
633 + // phpcs:ignore
499 634 echo $exporter->get_data( $items, array() );
500 635 die();
501 636 }
502 637 }
@@ -502,13 +637,13 @@
502 637 }
503 638 }
504 639
505 640 private function try_export_logs() {
506 - if ( $this->user_has_access() && isset( $_POST['export-csv'] ) && check_admin_referer( 'wp_rest' ) ) {
507 - if ( $this->get_menu_page() === 'log' ) {
508 - RE_Log::export_to_csv();
509 - } else {
510 - RE_404::export_to_csv();
641 + if ( Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_IO_MANAGE ) && isset( $_POST['export-csv'] ) && check_admin_referer( 'wp_rest' ) ) {
642 + if ( $this->get_current_page() === 'log' ) {
643 + Red_Redirect_Log::export_to_csv();
644 + } elseif ( $this->get_current_page() === '404s' ) {
645 + Red_404_Log::export_to_csv();
511 646 }
512 647
513 648 die();
514 649 }
@@ -514,13 +649,20 @@
514 649 }
515 650 }
516 651
517 652 private function try_export_redirects() {
518 - if ( $this->user_has_access() && $_GET['sub'] === 'io' && isset( $_GET['exporter'] ) && isset( $_GET['export'] ) && check_admin_referer( 'wp_rest' ) ) {
653 + // phpcs:ignore
654 + if ( ! isset( $_GET['sub'] ) || $_GET['sub'] !== 'io' ) {
655 + return;
656 + }
657 +
658 + if ( Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_IO_MANAGE ) && isset( $_GET['exporter'] ) && isset( $_GET['export'] ) && check_admin_referer( 'wp_rest' ) ) {
519 659 $export = Red_FileIO::export( $_GET['export'], $_GET['exporter'] );
520 660
521 661 if ( $export !== false ) {
522 662 $export['exporter']->force_download();
663 +
664 + // phpcs:ignore
523 665 echo $export['data'];
524 666 die();
525 667 }
526 668 }
@@ -529,4 +671,15 @@
529 671
530 672 register_activation_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_activated' ) );
531 673
532 674 add_action( 'init', array( 'Redirection_Admin', 'init' ) );
675 +
676 +// This is causing a lot of problems with the REST API - disable qTranslate
677 +add_filter( 'qtranslate_language_detect_redirect', function( $lang, $url ) {
678 + $url = Redirection_Request::get_request_url();
679 +
680 + if ( strpos( $url, '/wp-json/' ) !== false || strpos( $url, '?rest_route' ) !== false ) {
681 + return false;
682 + }
683 +
684 + return $lang;
685 +}, 10, 2 );