PluginProbe
Redirection / 5.1
Redirection v5.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 / redirection-admin.php

redirection-admin.php in Redirection 5.1, at redirection-admin.php

684 lines 21.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
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';
8
9 define( 'RED_DEFAULT_PER_PAGE', 25 );
10 define( 'RED_MAX_PER_PAGE', 200 );
11
12 class Redirection_Admin {
13 private static $instance = null;
14 private $monitor;
15 private $fixit_failed = false;
16
17 public static function init() {
18 if ( is_null( self::$instance ) ) {
19 self::$instance = new Redirection_Admin();
20 }
21
22 return self::$instance;
23 }
24
25 public function __construct() {
26 add_action( 'admin_menu', [ $this, 'admin_menu' ] );
27 add_action( 'admin_notices', [ $this, 'update_nag' ] );
28 add_action( '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 );
37
38 if ( defined( 'REDIRECTION_FLYING_SOLO' ) && REDIRECTION_FLYING_SOLO ) {
39 add_filter( 'script_loader_src', [ $this, 'flying_solo' ], 10, 2 );
40 }
41
42 register_deactivation_hook( REDIRECTION_FILE, [ 'Redirection_Admin', 'plugin_deactivated' ] );
43 register_uninstall_hook( REDIRECTION_FILE, [ 'Redirection_Admin', 'plugin_uninstall' ] );
44
45 $this->monitor = new Red_Monitor( red_get_options() );
46 $this->run_hacks();
47 }
48
49 // These are only called on the single standard site, or in the network admin of the multisite - they run across all available sites
50 public static function plugin_activated() {
51 Red_Database::apply_to_sites( function() {
52 Red_Flusher::clear();
53 red_set_options();
54 } );
55 }
56
57 // These are only called on the single standard site, or in the network admin of the multisite - they run across all available sites
58 public static function plugin_deactivated() {
59 Red_Database::apply_to_sites( function() {
60 Red_Flusher::clear();
61 } );
62 }
63
64 // These are only called on the single standard site, or in the network admin of the multisite - they run across all available sites
65 public static function plugin_uninstall() {
66 $database = Red_Database::get_latest_database();
67
68 Red_Database::apply_to_sites( function() use ( $database ) {
69 $database->remove();
70 } );
71 }
72
73 /**
74 * Show the database upgrade nag
75 *
76 * @return void
77 */
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
93 $status = new Red_Database_Status();
94
95 $message = false;
96 if ( $status->needs_installing() ) {
97 /* translators: 1: URL to plugin page */
98 $message = sprintf( __( 'Please complete your <a href="%s">Redirection setup</a> to activate the plugin.', 'redirection' ), esc_url( $this->get_plugin_url() ) );
99 } elseif ( $status->needs_updating() ) {
100 /* translators: 1: URL to plugin page, 2: current version, 3: target version */
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() ) );
102 }
103
104 if ( ! $message || strpos( Redirection_Request::get_request_url(), 'page=redirection.php' ) !== false ) {
105 return;
106 }
107
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>';
111 }
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 }
138
139 // 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
140 // then this can prevent Redirection running and it's a little sensitive about that. We use the nuclear option here to disable
141 // all other JS while viewing Redirection
142 public function flying_solo( $src, $handle ) {
143 if ( isset( $_SERVER['REQUEST_URI'] ) && strpos( $_SERVER['REQUEST_URI'], 'page=redirection.php' ) !== false ) {
144 if ( substr( $src, 0, 4 ) === 'http' && $handle !== 'redirection' && strpos( $src, 'plugins' ) !== false ) {
145 if ( $this->ignore_this_plugin( $src ) ) {
146 return false;
147 }
148 }
149 }
150
151 return $src;
152 }
153
154 private function ignore_this_plugin( $src ) {
155 $ignore = array(
156 'mootools',
157 'wp-seo-',
158 'authenticate',
159 'wordpress-seo',
160 'yikes',
161 );
162
163 foreach ( $ignore as $text ) {
164 if ( strpos( $src, $text ) !== false ) {
165 return true;
166 }
167 }
168
169 return false;
170 }
171
172 public function flush_schedule( $options ) {
173 Red_Flusher::schedule();
174 return $options;
175 }
176
177 public function set_per_page( $status, $option, $value ) {
178 if ( $option === 'redirection_log_per_page' ) {
179 $value = max( 1, min( intval( $value, 10 ), RED_MAX_PER_PAGE ) );
180 return $value;
181 }
182
183 return $status;
184 }
185
186 public function plugin_settings( $links ) {
187 $status = new Red_Database_Status();
188 if ( $status->needs_updating() ) {
189 array_unshift( $links, '<a style="color: red" href="' . esc_url( $this->get_plugin_url() ) . '&amp;sub=support">' . __( 'Upgrade Database', 'redirection' ) . '</a>' );
190 }
191
192 array_unshift( $links, '<a href="' . esc_url( $this->get_plugin_url() ) . '&amp;sub=options">' . __( 'Settings', 'redirection' ) . '</a>' );
193 return $links;
194 }
195
196 public function plugin_row_meta( $plugin_meta, $plugin_file, $plugin_data, $status ) {
197 if ( $plugin_file === basename( dirname( REDIRECTION_FILE ) ) . '/' . basename( REDIRECTION_FILE ) ) {
198 $plugin_data['Description'] .= '<p>' . __( 'Please upgrade your database', 'redirection' ) . '</p>';
199 }
200
201 return $plugin_meta;
202 }
203
204 private function get_plugin_url() {
205 return admin_url( 'tools.php?page=' . basename( REDIRECTION_FILE ) );
206 }
207
208 private function get_first_available_page_url() {
209 $pages = Redirection_Capabilities::get_available_pages();
210
211 if ( count( $pages ) > 0 ) {
212 return $this->get_plugin_url() . ( $pages[0] === 'redirect' ? '' : '&sub=' . rawurlencode( $pages[0] ) );
213 }
214
215 return admin_url();
216 }
217
218 public function redirection_head() {
219 global $wp_version;
220
221 // Does user have access to this page?
222 if ( $this->get_current_page() === false ) {
223 // Redirect to root plugin page
224 wp_safe_redirect( $this->get_first_available_page_url() );
225 die();
226 }
227
228 if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( $_REQUEST['_wpnonce'], 'wp_rest' ) ) {
229 if ( $_REQUEST['action'] === 'fixit' ) {
230 $this->run_fixit();
231 } elseif ( $_REQUEST['action'] === 'rest_api' ) {
232 $this->set_rest_api( intval( $_REQUEST['rest_api'], 10 ) );
233 }
234 }
235
236 $build = REDIRECTION_VERSION . '-' . REDIRECTION_BUILD;
237 $preload = $this->get_preload_data();
238 $options = red_get_options();
239 $versions = array(
240 'Plugin: ' . REDIRECTION_VERSION . ' ' . REDIRECTION_DB_VERSION,
241 'WordPress: ' . $wp_version . ' (' . ( is_multisite() ? 'multi' : 'single' ) . ')',
242 'PHP: ' . phpversion(),
243 'Browser: ' . Redirection_Request::get_user_agent(),
244 'JavaScript: ' . plugin_dir_url( REDIRECTION_FILE ) . 'redirection.js?ver=' . $build,
245 'REST API: ' . red_get_rest_api(),
246 );
247
248 $this->inject();
249
250 // Add contextual help to some pages
251 if ( in_array( $this->get_current_page(), [ 'redirect', 'log', '404s', 'groups' ], true ) ) {
252 add_screen_option( 'per_page', array(
253 /* translators: maximum number of log entries */
254 'label' => sprintf( __( 'Log entries (%d max)', 'redirection' ), RED_MAX_PER_PAGE ),
255 'default' => RED_DEFAULT_PER_PAGE,
256 'option' => 'redirection_log_per_page',
257 ) );
258 }
259
260 if ( defined( 'REDIRECTION_DEV_MODE' ) && REDIRECTION_DEV_MODE ) {
261 wp_enqueue_script( 'redirection', 'http://localhost:3312/redirection.js', array(), $build, true );
262 } else {
263 wp_enqueue_script( 'redirection', plugin_dir_url( REDIRECTION_FILE ) . 'redirection.js', array(), $build, true );
264 }
265
266 wp_enqueue_style( 'redirection', plugin_dir_url( REDIRECTION_FILE ) . 'redirection.css', array(), $build );
267
268 $is_new = false;
269
270 // phpcs:ignore
271 if ( isset( $_GET['page'] ) && $_GET['page'] === 'redirection.php' && strpos( REDIRECTION_VERSION, '-beta' ) === false ) {
272 $major_version = implode( '.', array_slice( explode( '.', REDIRECTION_VERSION ), 0, 2 ) );
273 $is_new = version_compare( $options['update_notice'], $major_version ) < 0;
274 }
275
276 $status = new Red_Database_Status();
277 $status->check_tables_exist();
278
279 $translations = $this->get_i18n_data();
280
281 wp_localize_script( 'redirection', 'Redirectioni10n', array(
282 'api' => [
283 'WP_API_root' => esc_url_raw( red_get_rest_api() ),
284 'WP_API_nonce' => wp_create_nonce( 'wp_rest' ),
285 'site_health' => admin_url( 'site-health.php' ),
286 'current' => $options['rest_api'],
287 'routes' => [
288 REDIRECTION_API_JSON => red_get_rest_api( REDIRECTION_API_JSON ),
289 REDIRECTION_API_JSON_INDEX => red_get_rest_api( REDIRECTION_API_JSON_INDEX ),
290 REDIRECTION_API_JSON_RELATIVE => red_get_rest_api( REDIRECTION_API_JSON_RELATIVE ),
291 ],
292 ],
293 'pluginBaseUrl' => plugins_url( '', REDIRECTION_FILE ),
294 'pluginRoot' => $this->get_plugin_url(),
295 'per_page' => $this->get_per_page(),
296 'locale' => [
297 'translations' => $translations,
298 'localeSlug' => get_locale(),
299 'Plural-Forms' => isset( $translations['plural-forms'] ) ? $translations['plural-forms'] : 'nplurals=2; plural=n != 1;',
300 ],
301 'settings' => $options,
302 'preload' => $preload,
303 'versions' => implode( "\n", $versions ),
304 'version' => REDIRECTION_VERSION,
305 'database' => $status->get_json(),
306 'caps' => [
307 'pages' => Redirection_Capabilities::get_available_pages(),
308 'capabilities' => Redirection_Capabilities::get_all_capabilities(),
309 ],
310 'update_notice' => $is_new ? $major_version : false,
311 ) );
312
313 $this->add_help_tab();
314 }
315
316 // Some plugins misbehave, so this attempts to 'fix' them so Redirection can get on with it's work
317 private function run_hacks() {
318 add_filter( 'ip-geo-block-admin', array( $this, 'ip_geo_block' ) );
319 }
320
321 /*
322 * This works around the IP Geo Block plugin being very aggressive and breaking Redirection
323 */
324 public function ip_geo_block( $validate ) {
325 $url = Redirection_Request::get_request_url();
326 $override = array(
327 'tools.php?page=redirection.php',
328 'action=red_proxy&rest_path=redirection',
329 );
330
331 foreach ( $override as $path ) {
332 if ( strpos( $url, $path ) !== false ) {
333 return array(
334 'result' => 'passed',
335 'auth' => false,
336 'asn' => false,
337 'code' => false,
338 'ip' => false,
339 );
340 }
341 }
342
343 return $validate;
344 }
345
346 private function run_fixit() {
347 if ( Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_SUPPORT_MANAGE ) ) {
348 require_once dirname( REDIRECTION_FILE ) . '/models/fixer.php';
349
350 $fixer = new Red_Fixer();
351 $result = $fixer->fix( $fixer->get_status() );
352
353 if ( is_wp_error( $result ) ) {
354 $this->fixit_failed = $result;
355 }
356 }
357 }
358
359 private function set_rest_api( $api ) {
360 if ( $api >= 0 && $api <= REDIRECTION_API_JSON_RELATIVE ) {
361 red_set_options( array( 'rest_api' => intval( $api, 10 ) ) );
362 }
363 }
364
365 private function get_preload_data() {
366 $status = new Red_Database_Status();
367
368 if ( $status->needs_installing() ) {
369 include_once __DIR__ . '/models/importer.php';
370
371 return [
372 'importers' => Red_Plugin_Importer::get_plugins(),
373 ];
374 }
375
376 if ( $this->get_current_page() === 'support' ) {
377 require_once dirname( REDIRECTION_FILE ) . '/models/fixer.php';
378
379 $fixer = new Red_Fixer();
380
381 return array(
382 'pluginStatus' => $fixer->get_json(),
383 );
384 }
385
386 return [];
387 }
388
389 private function add_help_tab() {
390 /* translators: URL */
391 $content = sprintf( __( 'You can find full documentation about using Redirection on the <a href="%s" target="_blank">redirection.me</a> support site.', 'redirection' ), 'https://redirection.me/support/?utm_source=redirection&utm_medium=plugin&utm_campaign=context-help' );
392 $title = __( 'Redirection Support', 'redirection' );
393
394 $current_screen = get_current_screen();
395 $current_screen->add_help_tab( array(
396 'id' => 'redirection',
397 'title' => 'Redirection',
398 'content' => "<h2>$title</h2><p>$content</p>",
399 ) );
400 }
401
402 private function get_per_page() {
403 $per_page = intval( get_user_meta( get_current_user_id(), 'redirection_log_per_page', true ), 10 );
404
405 return $per_page > 0 ? max( 5, min( $per_page, RED_MAX_PER_PAGE ) ) : RED_DEFAULT_PER_PAGE;
406 }
407
408 private function get_i18n_data() {
409 $locale = get_locale();
410
411 // WP 4.7
412 if ( function_exists( 'get_user_locale' ) ) {
413 $locale = get_user_locale();
414 }
415
416 $i18n_json = dirname( REDIRECTION_FILE ) . '/locale/json/redirection-' . $locale . '.json';
417
418 if ( is_file( $i18n_json ) && is_readable( $i18n_json ) ) {
419 // phpcs:ignore
420 $locale_data = @file_get_contents( $i18n_json );
421
422 if ( $locale_data ) {
423 return json_decode( $locale_data, true );
424 }
425 }
426
427 // Return empty if we have nothing to return so it doesn't fail when parsed in JS
428 return array();
429 }
430
431 public function admin_menu() {
432 $hook = add_management_page( 'Redirection', 'Redirection', Redirection_Capabilities::get_plugin_access(), basename( REDIRECTION_FILE ), [ $this, 'admin_screen' ] );
433 add_action( 'load-' . $hook, [ $this, 'redirection_head' ] );
434 }
435
436 private function check_minimum_wp() {
437 $wp_version = get_bloginfo( 'version' );
438
439 if ( version_compare( $wp_version, REDIRECTION_MIN_WP, '<' ) ) {
440 return false;
441 }
442
443 return true;
444 }
445
446 /**
447 * Update the cache key when updating or creating a redirect
448 *
449 * @return void
450 */
451 public function clear_cache() {
452 $settings = red_get_options();
453
454 if ( $settings['cache_key'] > 0 ) {
455 red_set_options( [ 'cache_key' => time() ] );
456 }
457 }
458
459 public function set_default_group( $id, $redirect ) {
460 red_set_options( array( 'last_group_id' => $redirect->get_group_id() ) );
461 }
462
463 public function admin_screen() {
464 if ( count( Redirection_Capabilities::get_all_capabilities() ) === 0 ) {
465 die( 'You do not have sufficient permissions to access this page.' );
466 }
467
468 if ( $this->check_minimum_wp() === false ) {
469 return $this->show_minimum_wordpress();
470 }
471
472 if ( $this->fixit_failed ) {
473 $this->show_fixit_failed();
474 }
475
476 Red_Flusher::schedule();
477
478 $this->show_main();
479 }
480
481 private function show_fixit_failed() {
482 ?>
483 <div class="notice notice-error">
484 <h1><?php echo esc_html( $this->fixit_failed->get_error_message() ); ?></h1>
485 <p><?php echo esc_html( $this->fixit_failed->get_error_data() ); ?></p>
486 </div>
487 <?php
488 }
489
490 private function show_minimum_wordpress() {
491 global $wp_version;
492
493 /* translators: 1: Expected WordPress version, 2: Actual WordPress version */
494 $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 );
495 ?>
496 <div class="react-error">
497 <h1><?php esc_html_e( 'Unable to load Redirection', 'redirection' ); ?></h1>
498 <p><?php echo esc_html( $wp_requirement ); ?></p>
499 </div>
500 <?php
501 }
502
503 private function show_load_fail() {
504 ?>
505 <div class="react-error" style="display: none">
506 <h1><?php esc_html_e( 'Unable to load Redirection ☹️', 'redirection' ); ?> v<?php echo esc_html( REDIRECTION_VERSION ); ?></h1>
507 <p><?php esc_html_e( "This may be caused by another plugin - look at your browser's error console for more details.", 'redirection' ); ?></p>
508 <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>
509 <p><?php _e( 'Also check if your browser is able to load <code>redirection.js</code>:', 'redirection' ); ?></p>
510 <p><code><?php echo esc_html( plugin_dir_url( REDIRECTION_FILE ) . 'redirection.js?ver=' . rawurlencode( REDIRECTION_VERSION ) . '-' . rawurlencode( REDIRECTION_BUILD ) ); ?></code></p>
511 <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>
512 <p><?php _e( 'Please see the <a href="https://redirection.me/support/problems/">list of common problems</a>.', 'redirection' ); ?></p>
513 <p><?php esc_html_e( 'If you think Redirection is at fault then create an issue.', 'redirection' ); ?></p>
514 <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>
515 <p>
516 <a class="button-primary" target="_blank" href="https://github.com/johngodley/redirection/issues/new?title=Problem%20starting%20Redirection%20<?php echo esc_attr( REDIRECTION_VERSION ); ?>">
517 <?php esc_html_e( 'Create Issue', 'redirection' ); ?>
518 </a>
519 </p>
520 </div>
521 <?php
522 }
523
524 private function show_main() {
525 ?>
526 <div id="react-modal"></div>
527 <div id="react-ui">
528 <div class="react-loading">
529 <h1><?php esc_html_e( 'Loading, please wait...', 'redirection' ); ?></h1>
530
531 <span class="react-loading-spinner"></span>
532 </div>
533 <noscript><?php esc_html_e( 'Please enable JavaScript', 'redirection' ); ?></noscript>
534
535 <?php $this->show_load_fail(); ?>
536 </div>
537
538 <script>
539 var prevError = window.onerror;
540 var errors = [];
541 var timeout = 0;
542 var timer = setInterval( function() {
543 if ( isRedirectionLoaded() ) {
544 resetAll();
545 } else if ( errors.length > 0 || timeout++ === 5 ) {
546 showError();
547 }
548 }, 5000 );
549
550 function isRedirectionLoaded() {
551 return typeof redirection !== 'undefined';
552 }
553
554 function showError() {
555 var errorText = "";
556
557 if ( errors.length > 0 ) {
558 errorText = "```\n" + errors.join( ',' ) + "\n```\n\n";
559 }
560
561 resetAll();
562 document.querySelector( '.react-loading' ).style.display = 'none';
563 document.querySelector( '.react-error' ).style.display = 'block';
564
565 if ( typeof Redirectioni10n !== 'undefined' && Redirectioni10n ) {
566 document.querySelector( '.versions' ).innerHTML = Redirectioni10n.versions.replace( /\n/g, '<br />' );
567 document.querySelector( '.react-error .button-primary' ).href += '&body=' + encodeURIComponent( errorText ) + encodeURIComponent( Redirectioni10n.versions );
568 }
569 }
570
571 function resetAll() {
572 clearInterval( timer );
573 window.onerror = prevError;
574 }
575
576 window.onerror = function( error, url, line ) {
577 console.error( error );
578 errors.push( error + ' ' + url + ' ' + line );
579 };
580 </script>
581 <?php
582 }
583
584 /**
585 * Get the current plugin page.
586 * Uses $_GET['sub'] to determine the current page unless a page is supplied.
587 *
588 * @param string $page Current page.
589 *
590 * @return string|boolean Current page, or false.
591 */
592 private function get_current_page( $page = false ) {
593 // $_GET['sub'] is validated below
594 // phpcs:ignore
595 if ( ! $page ) {
596 // phpcs:ignore
597 $page = isset( $_GET['sub'] ) ? $_GET['sub'] : 'redirect';
598 }
599
600 // Are we allowed to access this page?
601 if ( in_array( $page, Redirection_Capabilities::get_available_pages(), true ) ) {
602 // phpcs:ignore
603 return $page;
604 }
605
606 return false;
607 }
608
609 private function inject() {
610 // phpcs:ignore
611 if ( isset( $_GET['page'] ) && $this->get_current_page() !== 'redirect' && $_GET['page'] === 'redirection.php' ) {
612 $this->try_export_logs();
613 $this->try_export_redirects();
614 $this->try_export_rss();
615 }
616 }
617
618 public function try_export_rss() {
619 // phpcs:ignore
620 if ( isset( $_GET['token'] ) && isset( $_GET['sub'] ) && $_GET['sub'] === 'rss' && Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_REDIRECT_MANAGE ) ) {
621 $options = red_get_options();
622
623 // phpcs:ignore
624 if ( $_GET['token'] === $options['token'] && ! empty( $options['token'] ) ) {
625 // phpcs:ignore
626 $items = Red_Item::get_all_for_module( intval( $_GET['module'], 10 ) );
627
628 $exporter = Red_FileIO::create( 'rss' );
629 $exporter->force_download();
630
631 // phpcs:ignore
632 echo $exporter->get_data( $items, array() );
633 die();
634 }
635 }
636 }
637
638 private function try_export_logs() {
639 if ( Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_IO_MANAGE ) && isset( $_POST['export-csv'] ) && check_admin_referer( 'wp_rest' ) ) {
640 if ( $this->get_current_page() === 'log' ) {
641 Red_Redirect_Log::export_to_csv();
642 } elseif ( $this->get_current_page() === '404s' ) {
643 Red_404_Log::export_to_csv();
644 }
645
646 die();
647 }
648 }
649
650 private function try_export_redirects() {
651 // phpcs:ignore
652 if ( ! isset( $_GET['sub'] ) || $_GET['sub'] !== 'io' ) {
653 return;
654 }
655
656 if ( Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_IO_MANAGE ) && isset( $_GET['exporter'] ) && isset( $_GET['export'] ) && check_admin_referer( 'wp_rest' ) ) {
657 $export = Red_FileIO::export( $_GET['export'], $_GET['exporter'] );
658
659 if ( $export !== false ) {
660 $export['exporter']->force_download();
661
662 // phpcs:ignore
663 echo $export['data'];
664 die();
665 }
666 }
667 }
668 }
669
670 register_activation_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_activated' ) );
671
672 add_action( 'init', array( 'Redirection_Admin', 'init' ) );
673
674 // This is causing a lot of problems with the REST API - disable qTranslate
675 add_filter( 'qtranslate_language_detect_redirect', function( $lang, $url ) {
676 $url = Redirection_Request::get_request_url();
677
678 if ( strpos( $url, '/wp-json/' ) !== false || strpos( $url, '?rest_route' ) !== false ) {
679 return false;
680 }
681
682 return $lang;
683 }, 10, 2 );
684