PluginProbe
Redirection / 2.10
Redirection v2.10
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, 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( 'load-tools_page_redirection', array( $this, 'redirection_head' ) );
28 add_action( 'plugin_action_links_'.basename( dirname( REDIRECTION_FILE ) ).'/'.basename( REDIRECTION_FILE ), array( $this, 'plugin_settings' ), 10, 4 );
29 add_filter( 'redirection_save_options', array( $this, 'flush_schedule' ) );
30 add_filter( 'set-screen-option', array( $this, 'set_per_page' ), 10, 3 );
31
32 if ( defined( 'REDIRECTION_FLYING_SOLO' ) && REDIRECTION_FLYING_SOLO ) {
33 add_filter( 'script_loader_src', array( $this, 'flying_solo' ), 10, 2 );
34 }
35
36 register_deactivation_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_deactivated' ) );
37 register_uninstall_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_uninstall' ) );
38
39 $this->monitor = new Red_Monitor( red_get_options() );
40 $this->api = new Redirection_Api();
41 }
42
43 // These are only called on the single standard site, or in the network admin of the multisite - they run across all available sites
44 public static function plugin_activated() {
45 if ( is_network_admin() ) {
46 foreach ( get_sites() as $site ) {
47 switch_to_blog( $site->blog_id );
48
49 Redirection_Admin::update();
50 Red_Flusher::schedule();
51 red_set_options();
52
53 restore_current_blog();
54 }
55 } else {
56 Redirection_Admin::update();
57 Red_Flusher::schedule();
58 red_set_options();
59 }
60 }
61
62 // These are only called on the single standard site, or in the network admin of the multisite - they run across all available sites
63 public static function plugin_deactivated() {
64 if ( is_network_admin() ) {
65 foreach ( get_sites() as $site ) {
66 switch_to_blog( $site->blog_id );
67
68 Red_Flusher::clear();
69
70 restore_current_blog();
71 }
72 } else {
73 Red_Flusher::clear();
74 }
75 }
76
77 // These are only called on the single standard site, or in the network admin of the multisite - they run across all available sites
78 public static function plugin_uninstall() {
79 include_once dirname( REDIRECTION_FILE ).'/models/database.php';
80
81 $db = new RE_Database();
82
83 if ( is_network_admin() ) {
84 foreach ( get_sites() as $site ) {
85 switch_to_blog( $site->blog_id );
86
87 $db->remove( REDIRECTION_FILE );
88
89 restore_current_blog();
90 }
91 } else {
92 $db->remove( REDIRECTION_FILE );
93 }
94 }
95
96 private static function update() {
97 $version = get_option( 'redirection_version' );
98
99 Red_Flusher::schedule();
100
101 if ( $version !== REDIRECTION_DB_VERSION ) {
102 include_once dirname( REDIRECTION_FILE ).'/models/database.php';
103
104 $database = new RE_Database();
105
106 if ( $version === false ) {
107 $database->install();
108 }
109
110 $database->upgrade( $version, REDIRECTION_DB_VERSION );
111 }
112 }
113
114 // 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
115 // then this can prevent Redirection running, it's a little sensitive about that. We use the nuclear option here to disable
116 // all other JS while viewing Redirection
117 public function flying_solo( $src, $handle ) {
118 if ( isset( $_SERVER['REQUEST_URI'] ) && strpos( $_SERVER['REQUEST_URI'], 'page=redirection.php' ) !== false ) {
119 if ( substr( $src, 0, 4 ) === 'http' && $handle !== 'redirection' && strpos( $src, 'plugins' ) !== false ) {
120 if ( $this->ignore_this_plugin( $src ) ) {
121 return false;
122 }
123 }
124 }
125
126 return $src;
127 }
128
129 private function ignore_this_plugin( $src ) {
130 if ( strpos( $src, 'mootools' ) !== false ) {
131 return true;
132 }
133
134 if ( strpos( $src, 'wp-seo-' ) !== false ) {
135 return true;
136 }
137
138 return false;
139 }
140
141 public function flush_schedule( $options ) {
142 Red_Flusher::schedule();
143 return $options;
144 }
145
146 function set_per_page( $status, $option, $value ) {
147 if ( $option === 'redirection_log_per_page' ) {
148 return max( 1, min( intval( $value, 10 ), RED_MAX_PER_PAGE ) );
149 }
150
151 return $status;
152 }
153
154 function plugin_settings( $links ) {
155 $settings_link = '<a href="tools.php?page='.basename( REDIRECTION_FILE ).'&amp;sub=options">'.__( 'Settings', 'redirection' ).'</a>';
156 array_unshift( $links, $settings_link );
157 return $links;
158 }
159
160 function redirection_head() {
161 global $wp_version;
162
163 $build = REDIRECTION_VERSION.'-'.REDIRECTION_BUILD;
164 $options = red_get_options();
165 $versions = array(
166 'Plugin: '.REDIRECTION_VERSION,
167 'WordPress: '.$wp_version,
168 'PHP: '.phpversion(),
169 'Browser: '.Redirection_Request::get_user_agent(),
170 );
171
172 $this->inject();
173
174 if ( ! isset( $_GET['sub'] ) || ( isset( $_GET['sub'] ) && ( in_array( $_GET['sub'], array( 'log', '404s', 'groups' ) ) ) ) ) {
175 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' ) );
176 }
177
178 if ( defined( 'REDIRECTION_DEV_MODE' ) && REDIRECTION_DEV_MODE ) {
179 wp_enqueue_script( 'redirection', 'http://localhost:3312/redirection.js', array(), $build, true );
180 } else {
181 wp_enqueue_script( 'redirection', plugin_dir_url( REDIRECTION_FILE ).'redirection.js', array(), $build, true );
182 }
183
184 wp_enqueue_style( 'redirection', plugin_dir_url( REDIRECTION_FILE ).'redirection.css', array(), $build );
185
186 wp_localize_script( 'redirection', 'Redirectioni10n', array(
187 'WP_API_root' => admin_url( 'admin-ajax.php' ),
188 'WP_API_nonce' => wp_create_nonce( 'wp_rest' ),
189 'pluginBaseUrl' => plugins_url( '', REDIRECTION_FILE ),
190 'pluginRoot' => admin_url( 'tools.php?page=redirection.php' ),
191 'per_page' => $this->get_per_page(),
192 'locale' => $this->get_i18n_data(),
193 'localeSlug' => get_locale(),
194 'token' => $options['token'],
195 'autoGenerate' => $options['auto_target'],
196 'versions' => implode( "\n", $versions ),
197 'version' => REDIRECTION_VERSION,
198 ) );
199 }
200
201 private function get_per_page() {
202 $per_page = intval( get_user_meta( get_current_user_id(), 'redirection_log_per_page', true ), 10 );
203
204 return $per_page > 0 ? $per_page : RED_DEFAULT_PER_PAGE;
205 }
206
207 private function get_i18n_data() {
208 $i18n_json = REDIRECTION_FILE . 'locale/json/redirection-' . get_locale() . '.json';
209
210 if ( is_file( $i18n_json ) && is_readable( $i18n_json ) ) {
211 $locale_data = @file_get_contents( $i18n_json );
212
213 if ( $locale_data ) {
214 return $locale_data;
215 }
216 }
217
218 // Return empty if we have nothing to return so it doesn't fail when parsed in JS
219 return '{}';
220 }
221
222 function admin_menu() {
223 add_management_page( 'Redirection', 'Redirection', apply_filters( 'redirection_role', 'administrator' ), basename( REDIRECTION_FILE ), array( &$this, 'admin_screen' ) );
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