PluginProbe
Redirection / 5.5.2
Redirection v5.5.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.5.2, at redirection-admin.php

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