PluginProbe
Redirection / 2.10.1
Redirection v2.10.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 2.10.1, at redirection-admin.php

401 lines 12.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 include dirname( __FILE__ ).'/models/group.php';
4 include dirname( __FILE__ ).'/models/monitor.php';
5 include dirname( __FILE__ ).'/models/file-io.php';
6 include dirname( __FILE__ ).'/redirection-api.php';
7
8 define( 'RED_DEFAULT_PER_PAGE', 25 );
9 define( 'RED_MAX_PER_PAGE', 200 );
10
11 class Redirection_Admin {
12 private static $instance = null;
13 private $monitor;
14
15 static function init() {
16 if ( is_null( self::$instance ) ) {
17 self::$instance = new Redirection_Admin();
18
19 load_plugin_textdomain( 'redirection', false, dirname( plugin_basename( REDIRECTION_FILE ) ).'/locale/' );
20 }
21
22 return self::$instance;
23 }
24
25 function __construct() {
26 add_action( 'admin_menu', array( $this, 'admin_menu' ) );
27 add_action( 'plugin_action_links_'.basename( dirname( REDIRECTION_FILE ) ).'/'.basename( REDIRECTION_FILE ), array( $this, 'plugin_settings' ), 10, 4 );
28 add_filter( 'redirection_save_options', array( $this, 'flush_schedule' ) );
29 add_filter( 'set-screen-option', array( $this, 'set_per_page' ), 10, 3 );
30
31 if ( defined( 'REDIRECTION_FLYING_SOLO' ) && REDIRECTION_FLYING_SOLO ) {
32 add_filter( 'script_loader_src', array( $this, 'flying_solo' ), 10, 2 );
33 }
34
35 register_deactivation_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_deactivated' ) );
36 register_uninstall_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_uninstall' ) );
37
38 $this->monitor = new Red_Monitor( red_get_options() );
39 $this->api = new Redirection_Api();
40 }
41
42 // These are only called on the single standard site, or in the network admin of the multisite - they run across all available sites
43 public static function plugin_activated() {
44 if ( is_network_admin() ) {
45 foreach ( get_sites() as $site ) {
46 switch_to_blog( $site->blog_id );
47
48 Redirection_Admin::update();
49 Red_Flusher::schedule();
50 red_set_options();
51
52 restore_current_blog();
53 }
54 } else {
55 Redirection_Admin::update();
56 Red_Flusher::schedule();
57 red_set_options();
58 }
59 }
60
61 // These are only called on the single standard site, or in the network admin of the multisite - they run across all available sites
62 public static function plugin_deactivated() {
63 if ( is_network_admin() ) {
64 foreach ( get_sites() as $site ) {
65 switch_to_blog( $site->blog_id );
66
67 Red_Flusher::clear();
68
69 restore_current_blog();
70 }
71 } else {
72 Red_Flusher::clear();
73 }
74 }
75
76 // These are only called on the single standard site, or in the network admin of the multisite - they run across all available sites
77 public static function plugin_uninstall() {
78 include_once dirname( REDIRECTION_FILE ).'/models/database.php';
79
80 $db = new RE_Database();
81
82 if ( is_network_admin() ) {
83 foreach ( get_sites() as $site ) {
84 switch_to_blog( $site->blog_id );
85
86 $db->remove( REDIRECTION_FILE );
87
88 restore_current_blog();
89 }
90 } else {
91 $db->remove( REDIRECTION_FILE );
92 }
93 }
94
95 private static function update() {
96 $version = get_option( 'redirection_version' );
97
98 Red_Flusher::schedule();
99
100 if ( $version !== REDIRECTION_DB_VERSION ) {
101 include_once dirname( REDIRECTION_FILE ).'/models/database.php';
102
103 $database = new RE_Database();
104
105 if ( $version === false ) {
106 $database->install();
107 }
108
109 $database->upgrade( $version, REDIRECTION_DB_VERSION );
110 }
111 }
112
113 // 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
114 // then this can prevent Redirection running, it's a little sensitive about that. We use the nuclear option here to disable
115 // all other JS while viewing Redirection
116 public function flying_solo( $src, $handle ) {
117 if ( isset( $_SERVER['REQUEST_URI'] ) && strpos( $_SERVER['REQUEST_URI'], 'page=redirection.php' ) !== false ) {
118 if ( substr( $src, 0, 4 ) === 'http' && $handle !== 'redirection' && strpos( $src, 'plugins' ) !== false ) {
119 if ( $this->ignore_this_plugin( $src ) ) {
120 return false;
121 }
122 }
123 }
124
125 return $src;
126 }
127
128 private function ignore_this_plugin( $src ) {
129 if ( strpos( $src, 'mootools' ) !== false ) {
130 return true;
131 }
132
133 if ( strpos( $src, 'wp-seo-' ) !== false ) {
134 return true;
135 }
136
137 return false;
138 }
139
140 public function flush_schedule( $options ) {
141 Red_Flusher::schedule();
142 return $options;
143 }
144
145 function set_per_page( $status, $option, $value ) {
146 if ( $option === 'redirection_log_per_page' ) {
147 return max( 1, min( intval( $value, 10 ), RED_MAX_PER_PAGE ) );
148 }
149
150 return $status;
151 }
152
153 function plugin_settings( $links ) {
154 $settings_link = '<a href="tools.php?page='.basename( REDIRECTION_FILE ).'&amp;sub=options">'.__( 'Settings', 'redirection' ).'</a>';
155 array_unshift( $links, $settings_link );
156 return $links;
157 }
158
159 function redirection_head() {
160 global $wp_version;
161
162 $build = REDIRECTION_VERSION.'-'.REDIRECTION_BUILD;
163 $options = red_get_options();
164 $versions = array(
165 'Plugin: '.REDIRECTION_VERSION,
166 'WordPress: '.$wp_version,
167 'PHP: '.phpversion(),
168 'Browser: '.Redirection_Request::get_user_agent(),
169 );
170
171 $this->inject();
172
173 if ( ! isset( $_GET['sub'] ) || ( isset( $_GET['sub'] ) && ( in_array( $_GET['sub'], array( 'log', '404s', 'groups' ) ) ) ) ) {
174 add_screen_option( 'per_page', array( 'label' => sprintf( __( 'Log entries (%d max)', 'redirection' ), RED_MAX_PER_PAGE ), 'default' => RED_DEFAULT_PER_PAGE, 'option' => 'redirection_log_per_page' ) );
175 }
176
177 if ( defined( 'REDIRECTION_DEV_MODE' ) && REDIRECTION_DEV_MODE ) {
178 wp_enqueue_script( 'redirection', 'http://localhost:3312/redirection.js', array(), $build, true );
179 } else {
180 wp_enqueue_script( 'redirection', plugin_dir_url( REDIRECTION_FILE ).'redirection.js', array(), $build, true );
181 }
182
183 wp_enqueue_style( 'redirection', plugin_dir_url( REDIRECTION_FILE ).'redirection.css', array(), $build );
184
185 wp_localize_script( 'redirection', 'Redirectioni10n', array(
186 'WP_API_root' => admin_url( 'admin-ajax.php' ),
187 'WP_API_nonce' => wp_create_nonce( 'wp_rest' ),
188 'pluginBaseUrl' => plugins_url( '', REDIRECTION_FILE ),
189 'pluginRoot' => admin_url( 'tools.php?page=redirection.php' ),
190 'per_page' => $this->get_per_page(),
191 'locale' => $this->get_i18n_data(),
192 'localeSlug' => get_locale(),
193 'token' => $options['token'],
194 'autoGenerate' => $options['auto_target'],
195 'versions' => implode( "\n", $versions ),
196 'version' => REDIRECTION_VERSION,
197 ) );
198 }
199
200 private function get_per_page() {
201 $per_page = intval( get_user_meta( get_current_user_id(), 'redirection_log_per_page', true ), 10 );
202
203 return $per_page > 0 ? $per_page : RED_DEFAULT_PER_PAGE;
204 }
205
206 private function get_i18n_data() {
207 $i18n_json = REDIRECTION_FILE . 'locale/json/redirection-' . get_locale() . '.json';
208
209 if ( is_file( $i18n_json ) && is_readable( $i18n_json ) ) {
210 $locale_data = @file_get_contents( $i18n_json );
211
212 if ( $locale_data ) {
213 return $locale_data;
214 }
215 }
216
217 // Return empty if we have nothing to return so it doesn't fail when parsed in JS
218 return '{}';
219 }
220
221 function admin_menu() {
222 $hook = add_management_page( 'Redirection', 'Redirection', apply_filters( 'redirection_role', 'administrator' ), basename( REDIRECTION_FILE ), array( &$this, 'admin_screen' ) );
223 add_action( 'load-'.$hook, array( $this, 'redirection_head' ) );
224 }
225
226 private function check_minimum_wp() {
227 $wp_version = get_bloginfo( 'version' );
228
229 if ( version_compare( $wp_version, REDIRECTION_MIN_WP, '<' ) ) {
230 ?>
231 <div class="react-error">
232 <h1><?php _e( 'Unable to load Redirection', 'redirection' ); ?></h1>
233 <p style="text-align: left"><?php printf( __( 'Redirection requires WordPress v%1s, you are using v%2s - please update your WordPress', 'redirection' ), REDIRECTION_MIN_WP, $wp_version ); ?></p>
234 </div>
235 <?php
236 return false;
237 }
238
239 return true;
240 }
241
242 private function check_tables_exist() {
243 include_once dirname( REDIRECTION_FILE ).'/models/database.php';
244
245 $database = new RE_Database();
246 $status = $database->get_status();
247
248 if ( $status['status'] !== 'good' ) {
249 ?>
250 <div class="error">
251 <h3><?php _e( 'Redirection not installed properly', 'redirection' ); ?></h3>
252 <p style="text-align: left"><?php printf( __( 'Problems were detected with your database tables. Please visit the <a href="%s">support page</a> for more details.', 'redirection' ), 'tools.php?page=redirection.php&amp;sub=support' ); ?></p>
253 </div>
254 <?php
255
256 return false;
257 }
258
259 return true;
260 }
261
262 function admin_screen() {
263 $version = get_plugin_data( REDIRECTION_FILE );
264 $version = $version['Version'];
265
266 Redirection_Admin::update();
267
268 if ( $this->check_minimum_wp() === false ) {
269 return;
270 }
271
272 if ( $this->check_tables_exist() === false && ( ! isset( $_GET['sub'] ) || $_GET['sub'] !== 'support' ) ) {
273 return false;
274 }
275 ?>
276 <div id="react-ui">
277 <div class="react-loading">
278 <h1><?php _e( 'Loading, please wait...', 'redirection' ); ?></h1>
279
280 <span class="react-loading-spinner"></span>
281 </div>
282 <noscript>Please enable JavaScript</noscript>
283
284 <div class="react-error" style="display: none">
285 <h1><?php _e( 'Unable to load Redirection', 'redirection' ); ?> v<?php echo esc_html( $version ); ?></h1>
286 <p><?php _e( "This may be caused by another plugin - look at your browser's error console for more details.", 'redirection' ); ?></p>
287 <p><?php _e( 'If you are using a page caching plugin or service (CloudFlare, OVH, etc) then you can also try clearing that cache.', 'redirection' ); ?></p>
288 <p><?php _e( 'Also check if your browser is able to load <code>redirection.js</code>:', 'redirection' ); ?></p>
289 <p><code><?php echo esc_html( plugin_dir_url( REDIRECTION_FILE ).'redirection.js?ver='.urlencode( REDIRECTION_VERSION ).'-'.urlencode( REDIRECTION_BUILD ) ); ?></code></p>
290 <p><?php _e( "If you think Redirection is at fault then create an issue.", 'redirection' ); ?></p>
291 <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>
292 <p>
293 <a class="button-primary" target="_blank" href="https://github.com/johngodley/redirection/issues/new?title=Problem%20starting%20Redirection%20<?php echo esc_attr( $version ) ?>">
294 <?php _e( 'Create Issue', 'redirection' ); ?>
295 </a>
296 </p>
297 </div>
298 </div>
299
300 <script>
301 var prevError = window.onerror;
302 var errors = [];
303 var timeout = 0;
304 var timer = setInterval( function() {
305 if ( isRedirectionLoaded() ) {
306 resetAll();
307 } else if ( errors.length > 0 || timeout++ === 5 ) {
308 showError();
309 }
310 }, 5000 );
311
312 function isRedirectionLoaded() {
313 return typeof redirection !== 'undefined';
314 }
315
316 function showError() {
317 var errorText = "";
318
319 if ( errors.length > 0 ) {
320 errorText = "```\n" + errors.join( ',' ) + "\n```\n\n";
321 }
322
323 resetAll();
324 document.querySelector( '.react-loading' ).style.display = 'none';
325 document.querySelector( '.react-error' ).style.display = 'block';
326
327 if ( typeof Redirectioni10n !== 'undefined' ) {
328 document.querySelector( '.versions' ).innerHTML = Redirectioni10n.versions.replace( /\n/g, '<br />' );
329 document.querySelector( '.react-error .button-primary' ).href += '&body=' + encodeURIComponent( errorText ) + encodeURIComponent( Redirectioni10n.versions );
330 }
331 }
332
333 function resetAll() {
334 clearInterval( timer );
335 window.onerror = prevError;
336 }
337
338 window.onerror = function( error, url, line ) {
339 console.error( error );
340 errors.push( error + ' ' + url + ' ' + line );
341 };
342 </script>
343 <?php
344 }
345
346 private function user_has_access() {
347 return current_user_can( apply_filters( 'redirection_role', 'administrator' ) );
348 }
349
350 function inject() {
351 if ( isset( $_GET['page'] ) && isset( $_GET['sub'] ) && $_GET['page'] === 'redirection.php' ) {
352 $this->tryExportLogs();
353 $this->tryExportRedirects();
354 $this->tryExportRSS();
355 }
356 }
357
358 function tryExportRSS() {
359 if ( isset( $_GET['token'] ) && $_GET['sub'] === 'rss' ) {
360 $options = red_get_options();
361
362 if ( $_GET['token'] === $options['token'] && !empty( $options['token'] ) ) {
363 $items = Red_Item::get_all_for_module( intval( $_GET['module'] ) );
364
365 $exporter = Red_FileIO::create( 'rss' );
366 $exporter->force_download();
367 echo $exporter->get_data( $items, array() );
368 die();
369 }
370 }
371 }
372
373 private function tryExportLogs() {
374 if ( $this->user_has_access() && isset( $_POST['export-csv'] ) && check_admin_referer( 'wp_rest' ) ) {
375 if ( isset( $_GET['sub'] ) && $_GET['sub'] === 'log' ) {
376 RE_Log::export_to_csv();
377 } else {
378 RE_404::export_to_csv();
379 }
380
381 die();
382 }
383 }
384
385 private function tryExportRedirects() {
386 if ( $this->user_has_access() && $_GET['sub'] === 'io' && isset( $_GET['exporter'] ) && isset( $_GET['export'] ) ) {
387 $export = Red_FileIO::export( $_GET['export'], $_GET['exporter'] );
388
389 if ( $export !== false ) {
390 $export['exporter']->force_download();
391 echo $export['data'];
392 die();
393 }
394 }
395 }
396 }
397
398 register_activation_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_activated' ) );
399
400 add_action( 'init', array( 'Redirection_Admin', 'init' ) );
401