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
redirection / redirection-admin.php

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

686 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_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 );
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 $loop++;
138 }
139 }
140
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
142 // then this can prevent Redirection running and it's a little sensitive about that. We use the nuclear option here to disable
143 // all other JS while viewing Redirection
144 public function flying_solo( $src, $handle ) {
145 if ( isset( $_SERVER['REQUEST_URI'] ) && strpos( $_SERVER['REQUEST_URI'], 'page=redirection.php' ) !== false ) {
146 if ( substr( $src, 0, 4 ) === 'http' && $handle !== 'redirection' && strpos( $src, 'plugins' ) !== false ) {
147 if ( $this->ignore_this_plugin( $src ) ) {
148 return false;
149 }
150 }
151 }
152
153 return $src;
154 }
155
156 private function ignore_this_plugin( $src ) {
157 $ignore = array(
158 'mootools',
159 'wp-seo-',
160 'authenticate',
161 'wordpress-seo',
162 'yikes',
163 );
164
165 foreach ( $ignore as $text ) {
166 if ( strpos( $src, $text ) !== false ) {
167 return true;
168 }
169 }
170
171 return false;
172 }
173
174 public function flush_schedule( $options ) {
175 Red_Flusher::schedule();
176 return $options;
177 }
178
179 public function set_per_page( $status, $option, $value ) {
180 if ( $option === 'redirection_log_per_page' ) {
181 $value = max( 1, min( intval( $value, 10 ), RED_MAX_PER_PAGE ) );
182 return $value;
183 }
184
185 return $status;
186 }
187
188 public function plugin_settings( $links ) {
189 $status = new Red_Database_Status();
190 if ( $status->needs_updating() ) {
191 array_unshift( $links, '<a style="color: red" href="' . esc_url( $this->get_plugin_url() ) . '&amp;sub=support">' . __( 'Upgrade Database', 'redirection' ) . '</a>' );
192 }
193
194 array_unshift( $links, '<a href="' . esc_url( $this->get_plugin_url() ) . '&amp;sub=options">' . __( 'Settings', 'redirection' ) . '</a>' );
195 return $links;
196 }
197
198 public function plugin_row_meta( $plugin_meta, $plugin_file, $plugin_data, $status ) {
199 if ( $plugin_file === basename( dirname( REDIRECTION_FILE ) ) . '/' . basename( REDIRECTION_FILE ) ) {
200 $plugin_data['Description'] .= '<p>' . __( 'Please upgrade your database', 'redirection' ) . '</p>';
201 }
202
203 return $plugin_meta;
204 }
205
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() {
221 global $wp_version;
222
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 }
229
230 if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( $_REQUEST['_wpnonce'], 'wp_rest' ) ) {
231 if ( $_REQUEST['action'] === 'fixit' ) {
232 $this->run_fixit();
233 } elseif ( $_REQUEST['action'] === 'rest_api' ) {
234 $this->set_rest_api( intval( $_REQUEST['rest_api'], 10 ) );
235 }
236 }
237
238 $build = REDIRECTION_VERSION . '-' . REDIRECTION_BUILD;
239 $preload = $this->get_preload_data();
240 $options = red_get_options();
241 $versions = array(
242 'Plugin: ' . REDIRECTION_VERSION . ' ' . REDIRECTION_DB_VERSION,
243 'WordPress: ' . $wp_version . ' (' . ( is_multisite() ? 'multi' : 'single' ) . ')',
244 'PHP: ' . phpversion(),
245 'Browser: ' . Redirection_Request::get_user_agent(),
246 'JavaScript: ' . plugin_dir_url( REDIRECTION_FILE ) . 'redirection.js?ver=' . $build,
247 'REST API: ' . red_get_rest_api(),
248 );
249
250 $this->inject();
251
252 // Add contextual help to some pages
253 if ( in_array( $this->get_current_page(), [ 'redirect', 'log', '404s', 'groups' ], true ) ) {
254 add_screen_option( 'per_page', array(
255 /* translators: maximum number of log entries */
256 'label' => sprintf( __( 'Log entries (%d max)', 'redirection' ), RED_MAX_PER_PAGE ),
257 'default' => RED_DEFAULT_PER_PAGE,
258 'option' => 'redirection_log_per_page',
259 ) );
260 }
261
262 if ( defined( 'REDIRECTION_DEV_MODE' ) && REDIRECTION_DEV_MODE ) {
263 wp_enqueue_script( 'redirection', 'http://localhost:3312/redirection.js', array(), $build, true );
264 } else {
265 wp_enqueue_script( 'redirection', plugin_dir_url( REDIRECTION_FILE ) . 'redirection.js', array(), $build, true );
266 }
267
268 wp_enqueue_style( 'redirection', plugin_dir_url( REDIRECTION_FILE ) . 'redirection.css', array(), $build );
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
278 $status = new Red_Database_Status();
279 $status->check_tables_exist();
280
281 $translations = $this->get_i18n_data();
282
283 wp_localize_script( 'redirection', 'Redirectioni10n', array(
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 ],
295 'pluginBaseUrl' => plugins_url( '', REDIRECTION_FILE ),
296 'pluginRoot' => $this->get_plugin_url(),
297 'per_page' => $this->get_per_page(),
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 ],
303 'settings' => $options,
304 'preload' => $preload,
305 'versions' => implode( "\n", $versions ),
306 'version' => REDIRECTION_VERSION,
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,
313 ) );
314
315 $this->add_help_tab();
316 }
317
318 // Some plugins misbehave, so this attempts to 'fix' them so Redirection can get on with it's work
319 private function run_hacks() {
320 add_filter( 'ip-geo-block-admin', array( $this, 'ip_geo_block' ) );
321 }
322
323 /*
324 * This works around the IP Geo Block plugin being very aggressive and breaking Redirection
325 */
326 public function ip_geo_block( $validate ) {
327 $url = Redirection_Request::get_request_url();
328 $override = array(
329 'tools.php?page=redirection.php',
330 'action=red_proxy&rest_path=redirection',
331 );
332
333 foreach ( $override as $path ) {
334 if ( strpos( $url, $path ) !== false ) {
335 return array(
336 'result' => 'passed',
337 'auth' => false,
338 'asn' => false,
339 'code' => false,
340 'ip' => false,
341 );
342 }
343 }
344
345 return $validate;
346 }
347
348 private function run_fixit() {
349 if ( Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_SUPPORT_MANAGE ) ) {
350 require_once dirname( REDIRECTION_FILE ) . '/models/fixer.php';
351
352 $fixer = new Red_Fixer();
353 $result = $fixer->fix( $fixer->get_status() );
354
355 if ( is_wp_error( $result ) ) {
356 $this->fixit_failed = $result;
357 }
358 }
359 }
360
361 private function set_rest_api( $api ) {
362 if ( $api >= 0 && $api <= REDIRECTION_API_JSON_RELATIVE ) {
363 red_set_options( array( 'rest_api' => intval( $api, 10 ) ) );
364 }
365 }
366
367 private function get_preload_data() {
368 $status = new Red_Database_Status();
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
383 return array(
384 'pluginStatus' => $fixer->get_json(),
385 );
386 }
387
388 return [];
389 }
390
391 private function add_help_tab() {
392 /* translators: URL */
393 $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' );
394 $title = __( 'Redirection Support', 'redirection' );
395
396 $current_screen = get_current_screen();
397 $current_screen->add_help_tab( array(
398 'id' => 'redirection',
399 'title' => 'Redirection',
400 'content' => "<h2>$title</h2><p>$content</p>",
401 ) );
402 }
403
404 private function get_per_page() {
405 $per_page = intval( get_user_meta( get_current_user_id(), 'redirection_log_per_page', true ), 10 );
406
407 return $per_page > 0 ? max( 5, min( $per_page, RED_MAX_PER_PAGE ) ) : RED_DEFAULT_PER_PAGE;
408 }
409
410 private function get_i18n_data() {
411 $locale = get_locale();
412
413 // WP 4.7
414 if ( function_exists( 'get_user_locale' ) ) {
415 $locale = get_user_locale();
416 }
417
418 $i18n_json = dirname( REDIRECTION_FILE ) . '/locale/json/redirection-' . $locale . '.json';
419
420 if ( is_file( $i18n_json ) && is_readable( $i18n_json ) ) {
421 // phpcs:ignore
422 $locale_data = @file_get_contents( $i18n_json );
423
424 if ( $locale_data ) {
425 return json_decode( $locale_data, true );
426 }
427 }
428
429 // Return empty if we have nothing to return so it doesn't fail when parsed in JS
430 return array();
431 }
432
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' ] );
436 }
437
438 private function check_minimum_wp() {
439 $wp_version = get_bloginfo( 'version' );
440
441 if ( version_compare( $wp_version, REDIRECTION_MIN_WP, '<' ) ) {
442 return false;
443 }
444
445 return true;
446 }
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
461 public function set_default_group( $id, $redirect ) {
462 red_set_options( array( 'last_group_id' => $redirect->get_group_id() ) );
463 }
464
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
470 if ( $this->check_minimum_wp() === false ) {
471 return $this->show_minimum_wordpress();
472 }
473
474 if ( $this->fixit_failed ) {
475 $this->show_fixit_failed();
476 }
477
478 Red_Flusher::schedule();
479
480 $this->show_main();
481 }
482
483 private function show_fixit_failed() {
484 ?>
485 <div class="notice notice-error">
486 <h1><?php echo esc_html( $this->fixit_failed->get_error_message() ); ?></h1>
487 <p><?php echo esc_html( $this->fixit_failed->get_error_data() ); ?></p>
488 </div>
489 <?php
490 }
491
492 private function show_minimum_wordpress() {
493 global $wp_version;
494
495 /* translators: 1: Expected WordPress version, 2: Actual WordPress version */
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 );
497 ?>
498 <div class="react-error">
499 <h1><?php esc_html_e( 'Unable to load Redirection', 'redirection' ); ?></h1>
500 <p><?php echo esc_html( $wp_requirement ); ?></p>
501 </div>
502 <?php
503 }
504
505 private function show_load_fail() {
506 ?>
507 <div class="react-error" style="display: none">
508 <h1><?php esc_html_e( 'Unable to load Redirection ☹️', 'redirection' ); ?> v<?php echo esc_html( REDIRECTION_VERSION ); ?></h1>
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>
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>
511 <p><?php _e( 'Also check if your browser is able to load <code>redirection.js</code>:', 'redirection' ); ?></p>
512 <p><code><?php echo esc_html( plugin_dir_url( REDIRECTION_FILE ) . 'redirection.js?ver=' . rawurlencode( REDIRECTION_VERSION ) . '-' . rawurlencode( REDIRECTION_BUILD ) ); ?></code></p>
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>
514 <p><?php _e( 'Please see the <a href="https://redirection.me/support/problems/">list of common problems</a>.', 'redirection' ); ?></p>
515 <p><?php esc_html_e( 'If you think Redirection is at fault then create an issue.', 'redirection' ); ?></p>
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>
517 <p>
518 <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 ); ?>">
519 <?php esc_html_e( 'Create Issue', 'redirection' ); ?>
520 </a>
521 </p>
522 </div>
523 <?php
524 }
525
526 private function show_main() {
527 ?>
528 <div id="react-modal"></div>
529 <div id="react-ui">
530 <div class="react-loading">
531 <h1><?php esc_html_e( 'Loading, please wait...', 'redirection' ); ?></h1>
532
533 <span class="react-loading-spinner"></span>
534 </div>
535 <noscript><?php esc_html_e( 'Please enable JavaScript', 'redirection' ); ?></noscript>
536
537 <?php $this->show_load_fail(); ?>
538 </div>
539
540 <script>
541 var prevError = window.onerror;
542 var errors = [];
543 var timeout = 0;
544 var timer = setInterval( function() {
545 if ( isRedirectionLoaded() ) {
546 resetAll();
547 } else if ( errors.length > 0 || timeout++ === 5 ) {
548 showError();
549 }
550 }, 5000 );
551
552 function isRedirectionLoaded() {
553 return typeof redirection !== 'undefined';
554 }
555
556 function showError() {
557 var errorText = "";
558
559 if ( errors.length > 0 ) {
560 errorText = "```\n" + errors.join( ',' ) + "\n```\n\n";
561 }
562
563 resetAll();
564 document.querySelector( '.react-loading' ).style.display = 'none';
565 document.querySelector( '.react-error' ).style.display = 'block';
566
567 if ( typeof Redirectioni10n !== 'undefined' && Redirectioni10n ) {
568 document.querySelector( '.versions' ).innerHTML = Redirectioni10n.versions.replace( /\n/g, '<br />' );
569 document.querySelector( '.react-error .button-primary' ).href += '&body=' + encodeURIComponent( errorText ) + encodeURIComponent( Redirectioni10n.versions );
570 }
571 }
572
573 function resetAll() {
574 clearInterval( timer );
575 window.onerror = prevError;
576 }
577
578 window.onerror = function( error, url, line ) {
579 console.error( error );
580 errors.push( error + ' ' + url + ' ' + line );
581 };
582 </script>
583 <?php
584 }
585
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;
609 }
610
611 private function inject() {
612 // phpcs:ignore
613 if ( isset( $_GET['page'] ) && $this->get_current_page() !== 'redirect' && $_GET['page'] === 'redirection.php' ) {
614 $this->try_export_logs();
615 $this->try_export_redirects();
616 $this->try_export_rss();
617 }
618 }
619
620 public function try_export_rss() {
621 // phpcs:ignore
622 if ( isset( $_GET['token'] ) && isset( $_GET['sub'] ) && $_GET['sub'] === 'rss' && Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_REDIRECT_MANAGE ) ) {
623 $options = red_get_options();
624
625 // phpcs:ignore
626 if ( $_GET['token'] === $options['token'] && ! empty( $options['token'] ) ) {
627 // phpcs:ignore
628 $items = Red_Item::get_all_for_module( intval( $_GET['module'], 10 ) );
629
630 $exporter = Red_FileIO::create( 'rss' );
631 $exporter->force_download();
632
633 // phpcs:ignore
634 echo $exporter->get_data( $items, array() );
635 die();
636 }
637 }
638 }
639
640 private function try_export_logs() {
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();
646 }
647
648 die();
649 }
650 }
651
652 private function try_export_redirects() {
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' ) ) {
659 $export = Red_FileIO::export( $_GET['export'], $_GET['exporter'] );
660
661 if ( $export !== false ) {
662 $export['exporter']->force_download();
663
664 // phpcs:ignore
665 echo $export['data'];
666 die();
667 }
668 }
669 }
670 }
671
672 register_activation_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_activated' ) );
673
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 );
686