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

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

706 lines 22.5 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 add_filter( 'load_script_translation_file', [ $this, 'load_script_translation_file' ], 10, 3 );
38
39 if ( defined( 'REDIRECTION_FLYING_SOLO' ) && REDIRECTION_FLYING_SOLO ) {
40 add_filter( 'script_loader_src', [ $this, 'flying_solo' ], 10, 2 );
41 }
42
43 register_deactivation_hook( REDIRECTION_FILE, [ 'Redirection_Admin', 'plugin_deactivated' ] );
44 register_uninstall_hook( REDIRECTION_FILE, [ 'Redirection_Admin', 'plugin_uninstall' ] );
45
46 $this->monitor = new Red_Monitor( red_get_options() );
47 $this->run_hacks();
48 }
49
50 /**
51 * Massage the Redirection WP translations.
52 *
53 * @param [type] $file
54 * @param [type] $handle
55 * @param [type] $domain
56 * @return void
57 */
58 public function load_script_translation_file( $file, $handle, $domain ) {
59 if ( $domain === 'redirection' ) {
60 return preg_replace( '/-\w*\./', '.', $file );
61 }
62
63 return $file;
64 }
65
66 // These are only called on the single standard site, or in the network admin of the multisite - they run across all available sites
67 public static function plugin_activated() {
68 Red_Database::apply_to_sites( function() {
69 Red_Flusher::clear();
70 red_set_options();
71 } );
72 }
73
74 // These are only called on the single standard site, or in the network admin of the multisite - they run across all available sites
75 public static function plugin_deactivated() {
76 Red_Database::apply_to_sites( function() {
77 Red_Flusher::clear();
78 } );
79 }
80
81 // These are only called on the single standard site, or in the network admin of the multisite - they run across all available sites
82 public static function plugin_uninstall() {
83 $database = Red_Database::get_latest_database();
84
85 Red_Database::apply_to_sites( function() use ( $database ) {
86 $database->remove();
87 } );
88 }
89
90 /**
91 * Show the database upgrade nag
92 *
93 * @return void
94 */
95 public function update_nag() {
96 $options = red_get_options();
97
98 // Is the site configured to upgrade automatically?
99 if ( $options['plugin_update'] === 'admin' ) {
100 $this->automatic_upgrade();
101 return;
102 }
103
104 // Can the user perform a manual database upgrade?
105 if ( ! Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_OPTION_MANAGE ) ) {
106 return;
107 }
108
109 // Default manual update, with nag
110 $status = new Red_Database_Status();
111
112 $message = false;
113 if ( $status->needs_installing() ) {
114 /* translators: 1: URL to plugin page */
115 $message = sprintf( __( 'Please complete your <a href="%s">Redirection setup</a> to activate the plugin.', 'redirection' ), esc_url( $this->get_plugin_url() ) );
116 } elseif ( $status->needs_updating() ) {
117 /* translators: 1: URL to plugin page, 2: current version, 3: target version */
118 $message = sprintf( __( 'Redirection\'s database needs to be updated - <a href="%1$1s">click to update</a>.', 'redirection' ), esc_url( $this->get_plugin_url() ) );
119 }
120
121 if ( ! $message || strpos( Redirection_Request::get_request_url(), 'page=redirection.php' ) !== false ) {
122 return;
123 }
124
125 // Known HTML and so isn't escaped
126 // phpcs:ignore
127 echo '<div class="update-nag notice notice-warning" style="width: 95%">' . $message . '</div>';
128 }
129
130 /**
131 * Perform an automatic DB upgrade
132 *
133 * @return void
134 */
135 private function automatic_upgrade() {
136 $loop = 0;
137 $status = new Red_Database_Status();
138 $database = new Red_Database();
139
140 // Loop until the DB is upgraded, or until a max is exceeded (just in case)
141 while ( $loop < 20 ) {
142 if ( ! $status->needs_updating() ) {
143 break;
144 }
145
146 $database->apply_upgrade( $status );
147
148 if ( $status->is_error() ) {
149 // If an error occurs then switch to 'prompt' mode and let the user deal with it.
150 red_set_options( [ 'plugin_update' => 'prompt' ] );
151 return;
152 }
153
154 $loop++;
155 }
156 }
157
158 // 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
159 // then this can prevent Redirection running and it's a little sensitive about that. We use the nuclear option here to disable
160 // all other JS while viewing Redirection
161 public function flying_solo( $src, $handle ) {
162 if ( isset( $_SERVER['REQUEST_URI'] ) && strpos( $_SERVER['REQUEST_URI'], 'page=redirection.php' ) !== false ) {
163 if ( substr( $src, 0, 4 ) === 'http' && $handle !== 'redirection' && strpos( $src, 'plugins' ) !== false ) {
164 if ( $this->ignore_this_plugin( $src ) ) {
165 return false;
166 }
167 }
168 }
169
170 return $src;
171 }
172
173 private function ignore_this_plugin( $src ) {
174 $ignore = array(
175 'mootools',
176 'wp-seo-',
177 'authenticate',
178 'wordpress-seo',
179 'yikes',
180 );
181
182 foreach ( $ignore as $text ) {
183 if ( strpos( $src, $text ) !== false ) {
184 return true;
185 }
186 }
187
188 return false;
189 }
190
191 public function flush_schedule( $options ) {
192 Red_Flusher::schedule();
193 return $options;
194 }
195
196 public function set_per_page( $status, $option, $value ) {
197 if ( $option === 'redirection_log_per_page' ) {
198 $value = max( 1, min( intval( $value, 10 ), RED_MAX_PER_PAGE ) );
199 return $value;
200 }
201
202 return $status;
203 }
204
205 public function plugin_settings( $links ) {
206 $status = new Red_Database_Status();
207 if ( $status->needs_updating() ) {
208 array_unshift( $links, '<a style="color: red" href="' . esc_url( $this->get_plugin_url() ) . '&amp;sub=support">' . __( 'Upgrade Database', 'redirection' ) . '</a>' );
209 }
210
211 array_unshift( $links, '<a href="' . esc_url( $this->get_plugin_url() ) . '&amp;sub=options">' . __( 'Settings', 'redirection' ) . '</a>' );
212 return $links;
213 }
214
215 public function plugin_row_meta( $plugin_meta, $plugin_file, $plugin_data, $status ) {
216 if ( $plugin_file === basename( dirname( REDIRECTION_FILE ) ) . '/' . basename( REDIRECTION_FILE ) ) {
217 $plugin_data['Description'] .= '<p>' . __( 'Please upgrade your database', 'redirection' ) . '</p>';
218 }
219
220 return $plugin_meta;
221 }
222
223 private function get_plugin_url() {
224 return admin_url( 'tools.php?page=' . basename( REDIRECTION_FILE ) );
225 }
226
227 private function get_first_available_page_url() {
228 $pages = Redirection_Capabilities::get_available_pages();
229
230 if ( count( $pages ) > 0 ) {
231 return $this->get_plugin_url() . ( $pages[0] === 'redirect' ? '' : '&sub=' . rawurlencode( $pages[0] ) );
232 }
233
234 return admin_url();
235 }
236
237 public function redirection_head() {
238 global $wp_version;
239
240 // Does user have access to this page?
241 if ( $this->get_current_page() === false ) {
242 // Redirect to root plugin page
243 wp_safe_redirect( $this->get_first_available_page_url() );
244 die();
245 }
246
247 if ( isset( $_REQUEST['action'] ) && isset( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( $_REQUEST['_wpnonce'], 'wp_rest' ) ) {
248 if ( $_REQUEST['action'] === 'fixit' ) {
249 $this->run_fixit();
250 } elseif ( $_REQUEST['action'] === 'rest_api' ) {
251 $this->set_rest_api( intval( $_REQUEST['rest_api'], 10 ) );
252 }
253 }
254
255 $build = REDIRECTION_VERSION . '-' . REDIRECTION_BUILD;
256 $preload = $this->get_preload_data();
257 $options = red_get_options();
258 $versions = array(
259 'Plugin: ' . REDIRECTION_VERSION . ' ' . REDIRECTION_DB_VERSION,
260 'WordPress: ' . $wp_version . ' (' . ( is_multisite() ? 'multi' : 'single' ) . ')',
261 'PHP: ' . phpversion(),
262 'Browser: ' . Redirection_Request::get_user_agent(),
263 'JavaScript: ' . plugin_dir_url( REDIRECTION_FILE ) . 'redirection.js?ver=' . $build,
264 'REST API: ' . red_get_rest_api(),
265 );
266
267 $this->inject();
268
269 // Add contextual help to some pages
270 if ( in_array( $this->get_current_page(), [ 'redirect', 'log', '404s', 'groups' ], true ) ) {
271 add_screen_option( 'per_page', array(
272 /* translators: maximum number of log entries */
273 'label' => sprintf( __( 'Log entries (%d max)', 'redirection' ), RED_MAX_PER_PAGE ),
274 'default' => RED_DEFAULT_PER_PAGE,
275 'option' => 'redirection_log_per_page',
276 ) );
277 }
278
279 if ( defined( 'REDIRECTION_DEV_MODE' ) && REDIRECTION_DEV_MODE ) {
280 wp_enqueue_script( 'redirection', 'http://localhost:3312/redirection.js', array(), $build, true );
281 } else {
282 wp_enqueue_script( 'redirection', plugin_dir_url( REDIRECTION_FILE ) . 'redirection.js', array(), $build, true );
283 }
284
285 wp_enqueue_style( 'redirection', plugin_dir_url( REDIRECTION_FILE ) . 'redirection.css', array(), $build );
286
287 $is_new = false;
288 $major_version = implode( '.', array_slice( explode( '.', REDIRECTION_VERSION ), 0, 2 ) );
289
290 // phpcs:ignore
291 if ( isset( $_GET['page'] ) && $_GET['page'] === 'redirection.php' && strpos( REDIRECTION_VERSION, '-beta' ) === false ) {
292 $is_new = version_compare( $options['update_notice'], $major_version ) < 0;
293 }
294
295 $status = new Red_Database_Status();
296 $status->check_tables_exist();
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 // $_GET['sub'] is validated below
616 // phpcs:ignore
617 if ( ! $page ) {
618 // phpcs:ignore
619 $page = isset( $_GET['sub'] ) ? $_GET['sub'] : 'redirect';
620 }
621
622 // Are we allowed to access this page?
623 if ( in_array( $page, Redirection_Capabilities::get_available_pages(), true ) ) {
624 // phpcs:ignore
625 return $page;
626 }
627
628 return false;
629 }
630
631 private function inject() {
632 // phpcs:ignore
633 if ( isset( $_GET['page'] ) && $this->get_current_page() !== 'redirect' && $_GET['page'] === 'redirection.php' ) {
634 $this->try_export_logs();
635 $this->try_export_redirects();
636 $this->try_export_rss();
637 }
638 }
639
640 public function try_export_rss() {
641 // phpcs:ignore
642 if ( isset( $_GET['token'] ) && isset( $_GET['sub'] ) && $_GET['sub'] === 'rss' && Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_REDIRECT_MANAGE ) ) {
643 $options = red_get_options();
644
645 // phpcs:ignore
646 if ( $_GET['token'] === $options['token'] && ! empty( $options['token'] ) ) {
647 // phpcs:ignore
648 $items = Red_Item::get_all_for_module( intval( $_GET['module'], 10 ) );
649
650 $exporter = Red_FileIO::create( 'rss' );
651 $exporter->force_download();
652
653 // phpcs:ignore
654 echo $exporter->get_data( $items, array() );
655 die();
656 }
657 }
658 }
659
660 private function try_export_logs() {
661 if ( Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_IO_MANAGE ) && isset( $_POST['export-csv'] ) && check_admin_referer( 'wp_rest' ) ) {
662 if ( $this->get_current_page() === 'log' ) {
663 Red_Redirect_Log::export_to_csv();
664 } elseif ( $this->get_current_page() === '404s' ) {
665 Red_404_Log::export_to_csv();
666 }
667
668 die();
669 }
670 }
671
672 private function try_export_redirects() {
673 // phpcs:ignore
674 if ( ! isset( $_GET['sub'] ) || $_GET['sub'] !== 'io' ) {
675 return;
676 }
677
678 if ( Redirection_Capabilities::has_access( Redirection_Capabilities::CAP_IO_MANAGE ) && isset( $_GET['exporter'] ) && isset( $_GET['export'] ) && check_admin_referer( 'wp_rest' ) ) {
679 $export = Red_FileIO::export( $_GET['export'], $_GET['exporter'] );
680
681 if ( $export !== false ) {
682 $export['exporter']->force_download();
683
684 // phpcs:ignore
685 echo $export['data'];
686 die();
687 }
688 }
689 }
690 }
691
692 register_activation_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_activated' ) );
693
694 add_action( 'init', array( 'Redirection_Admin', 'init' ) );
695
696 // This is causing a lot of problems with the REST API - disable qTranslate
697 add_filter( 'qtranslate_language_detect_redirect', function( $lang, $url ) {
698 $url = Redirection_Request::get_request_url();
699
700 if ( strpos( $url, '/wp-json/' ) !== false || strpos( $url, '?rest_route' ) !== false ) {
701 return false;
702 }
703
704 return $lang;
705 }, 10, 2 );
706