Redirection - Version 2.3.13

Version Description

  • Split admin and front-end code out to streamline the loading a bit
  • Fix bad groups link when viewing redirects in a group, props to Patrick Fabre
  • Improved plugin activation/deactivation and cleanup
  • Improved log clearing
Download this release

Release Info

Developer johnny5
Plugin Icon 128x128 Redirection
Version 2.3.13
Comparing to
See all releases

Code changes from version 2.3.12 to 2.3.13

admin.css CHANGED
@@ -112,4 +112,17 @@ table.items table.edit th {
112
  font-weight: bold;
113
  }
114
 
 
 
 
 
 
 
 
 
 
115
 
 
 
 
 
112
  font-weight: bold;
113
  }
114
 
115
+ .donations {
116
+ padding: 10px 20px;
117
+ }
118
+
119
+ .donations li {
120
+ float: left;
121
+ text-align: center;
122
+ padding-right: 20px;
123
+ }
124
 
125
+ .donations li strong {
126
+ font-weight: bold;
127
+ font-size: 14px;
128
+ }
models/database.php CHANGED
@@ -1,35 +1,20 @@
1
  <?php
2
 
3
- class A_Redirector_URL {
4
- }
5
-
6
- class Redirector_Login {
7
- }
8
-
9
- class Redirector_LuckyDip {
10
- }
11
-
12
- class Redirector_Random {
13
- }
14
-
15
- class Redirector_Referrer {
16
- }
17
-
18
  class RE_Database {
19
- function get_charset() {
20
  global $wpdb;
21
 
22
  $charset_collate = '';
23
- if ( ! empty($wpdb->charset) )
24
  $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
25
 
26
- if ( ! empty($wpdb->collate) )
27
  $charset_collate .= " COLLATE $wpdb->collate";
28
 
29
  return $charset_collate;
30
  }
31
 
32
- function install() {
33
  global $wpdb;
34
 
35
  $charset_collate = $this->get_charset();
@@ -137,7 +122,7 @@ class RE_Database {
137
  }
138
  }
139
 
140
- function upgrade( $current, $target ) {
141
  global $wpdb;
142
 
143
  $wpdb->show_errors();
@@ -173,7 +158,7 @@ class RE_Database {
173
  return $success;
174
  }
175
 
176
- function upgrade_to_231() {
177
  global $wpdb;
178
 
179
  $charset_collate = $this->get_charset();
@@ -196,14 +181,14 @@ class RE_Database {
196
  ) $charset_collate;" );
197
  }
198
 
199
- function upgrade_from_20() {
200
  global $wpdb;
201
 
202
  $this->upgrade_from_21();
203
  $this->upgrade_from_22();
204
  }
205
 
206
- function upgrade_from_21() {
207
  global $wpdb;
208
 
209
  $wpdb->query( "ALTER TABLE `{$wpdb->prefix}redirection_items` ADD `title` varchar(50) NULL" );
@@ -211,13 +196,13 @@ class RE_Database {
211
  $this->upgrade_from_22();
212
  }
213
 
214
- function upgrade_from_22() {
215
  global $wpdb;
216
 
217
  $wpdb->query( "ALTER TABLE `{$wpdb->prefix}redirection_items` CHANGE `title` `title` varchar(50) NULL" );
218
  }
219
 
220
- function upgrade_to_216() {
221
  global $wpdb;
222
 
223
  $wpdb->query( "ALTER TABLE `{$wpdb->prefix}redirection_groups` ADD INDEX(module_id)" );
@@ -227,7 +212,7 @@ class RE_Database {
227
  $wpdb->query( "ALTER TABLE `{$wpdb->prefix}redirection_items` ADD INDEX(regex)" );
228
  }
229
 
230
- function upgrade_to_220() {
231
  global $wpdb;
232
 
233
  $wpdb->query( "ALTER TABLE `{$wpdb->prefix}redirection_items` ADD INDEX `group_idpos` (`group_id`,`position`)" );
@@ -244,7 +229,7 @@ class RE_Database {
244
  $wpdb->query( "ALTER TABLE `{$wpdb->prefix}redirection_modules` ADD INDEX `type` (`type`)" );
245
  }
246
 
247
- function remove( $plugin ) {
248
  global $wpdb;
249
 
250
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}redirection;" );
@@ -259,9 +244,5 @@ class RE_Database {
259
  delete_option( 'redirection_root' );
260
  delete_option( 'redirection_index' );
261
  delete_option( 'redirection_version' );
262
-
263
- $current = get_option( 'active_plugins' );
264
- array_splice( $current, array_search( basename( dirname( $plugin ) ).'/'.basename( $plugin ), $current ), 1 );
265
- update_option( 'active_plugins', $current );
266
  }
267
  }
1
  <?php
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  class RE_Database {
4
+ private function get_charset() {
5
  global $wpdb;
6
 
7
  $charset_collate = '';
8
+ if ( ! empty( $wpdb->charset ) )
9
  $charset_collate = "DEFAULT CHARACTER SET $wpdb->charset";
10
 
11
+ if ( ! empty( $wpdb->collate ) )
12
  $charset_collate .= " COLLATE $wpdb->collate";
13
 
14
  return $charset_collate;
15
  }
16
 
17
+ public function install() {
18
  global $wpdb;
19
 
20
  $charset_collate = $this->get_charset();
122
  }
123
  }
124
 
125
+ public function upgrade( $current, $target ) {
126
  global $wpdb;
127
 
128
  $wpdb->show_errors();
158
  return $success;
159
  }
160
 
161
+ private function upgrade_to_231() {
162
  global $wpdb;
163
 
164
  $charset_collate = $this->get_charset();
181
  ) $charset_collate;" );
182
  }
183
 
184
+ private function upgrade_from_20() {
185
  global $wpdb;
186
 
187
  $this->upgrade_from_21();
188
  $this->upgrade_from_22();
189
  }
190
 
191
+ private function upgrade_from_21() {
192
  global $wpdb;
193
 
194
  $wpdb->query( "ALTER TABLE `{$wpdb->prefix}redirection_items` ADD `title` varchar(50) NULL" );
196
  $this->upgrade_from_22();
197
  }
198
 
199
+ private function upgrade_from_22() {
200
  global $wpdb;
201
 
202
  $wpdb->query( "ALTER TABLE `{$wpdb->prefix}redirection_items` CHANGE `title` `title` varchar(50) NULL" );
203
  }
204
 
205
+ private function upgrade_to_216() {
206
  global $wpdb;
207
 
208
  $wpdb->query( "ALTER TABLE `{$wpdb->prefix}redirection_groups` ADD INDEX(module_id)" );
212
  $wpdb->query( "ALTER TABLE `{$wpdb->prefix}redirection_items` ADD INDEX(regex)" );
213
  }
214
 
215
+ private function upgrade_to_220() {
216
  global $wpdb;
217
 
218
  $wpdb->query( "ALTER TABLE `{$wpdb->prefix}redirection_items` ADD INDEX `group_idpos` (`group_id`,`position`)" );
229
  $wpdb->query( "ALTER TABLE `{$wpdb->prefix}redirection_modules` ADD INDEX `type` (`type`)" );
230
  }
231
 
232
+ public function remove( $plugin ) {
233
  global $wpdb;
234
 
235
  $wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}redirection;" );
244
  delete_option( 'redirection_root' );
245
  delete_option( 'redirection_index' );
246
  delete_option( 'redirection_version' );
 
 
 
 
247
  }
248
  }
models/flusher.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Red_Flusher {
4
+ const DELETE_HOOK = 'redirection_log_delete';
5
+ const DELETE_FREQ = 'daily';
6
+ const DELETE_MAX = 1000;
7
+ const DELETE_KEEP_ON = 15; // 15 minutes
8
+
9
+ public function flush() {
10
+ $total = 0;
11
+ $options = red_get_options();
12
+
13
+ $total += $this->expire_logs( $options['expire_redirect'] );
14
+ $total += $this->expire_404( $options['expire_404'] );
15
+
16
+ error_log('WPCRON: flushing '.$total);
17
+
18
+ if ( $total >= self::DELETE_MAX ) {
19
+ $next = time() + self::DELETE_KEEP_ON;
20
+
21
+ // There are still more logs to clear - keep on doing until we've clean or until the next normal event
22
+ if ( $next < wp_next_scheduled( self::DELETE_HOOK ) ) {
23
+ error_log('WPCRON: scheduling a single event '.date( 'Y-m-d H:i:s', time() + self::DELETE_KEEP_ON ));
24
+ wp_schedule_single_event( time() + ( self::DELETE_KEEP_ON * 60 ), self::DELETE_HOOK );
25
+ }
26
+ }
27
+
28
+ $this->optimize_logs();
29
+ }
30
+
31
+ private function optimize_logs() {
32
+ $rand = mt_rand( 1, 5000 );
33
+
34
+ if ( $rand === 11 )
35
+ $wpdb->query( "OPTIMIZE TABLE {$wpdb->prefix}redirection_logs" );
36
+ elseif ( $rand === 12 )
37
+ $wpdb->query( "OPTIMIZE TABLE {$wpdb->prefix}redirection_404" );
38
+ }
39
+
40
+ private function expire_logs( $expiry_time ) {
41
+ global $wpdb;
42
+
43
+ if ( $expiry_time > 0 ) {
44
+ $logs = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}redirection_logs WHERE created < DATE_SUB(NOW(), INTERVAL %d DAY)", $expiry_time ) );
45
+
46
+ if ( $logs > 0 ) {
47
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}redirection_logs WHERE created < DATE_SUB(NOW(), INTERVAL %d DAY) LIMIT %d", $expiry_time, self::DELETE_MAX ) );
48
+ return min( self::DELETE_MAX, $logs );
49
+ }
50
+ }
51
+
52
+ return 0;
53
+ }
54
+
55
+ private function expire_404( $expiry_time ) {
56
+ global $wpdb;
57
+
58
+ if ( $expiry_time > 0 ) {
59
+ $l404 = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}redirection_404 WHERE created < DATE_SUB(NOW(), INTERVAL %d DAY)", $expiry_time ) );
60
+
61
+ if ( $l404 > 0 ) {
62
+ $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}redirection_404 WHERE created < DATE_SUB(NOW(), INTERVAL %d DAY) LIMIT %d", $expiry_time, self::DELETE_MAX ) );
63
+ return min( self::DELETE_MAX, $l404 );
64
+ }
65
+ }
66
+
67
+ return 0;
68
+ }
69
+
70
+ public static function schedule() {
71
+ $options = red_get_options();
72
+
73
+ if ( $options['expire_redirect'] > 0 || $options['expire_404'] > 0 ) {
74
+ if ( !wp_next_scheduled( self::DELETE_HOOK ) )
75
+ wp_schedule_event( time(), self::DELETE_FREQ, self::DELETE_HOOK );
76
+ }
77
+ else
78
+ Red_Flusher::clear();
79
+ }
80
+
81
+ public static function clear() {
82
+ wp_clear_scheduled_hook( self::DELETE_HOOK );
83
+ }
84
+ }
models/redirect.php CHANGED
@@ -173,9 +173,7 @@ class Red_Item {
173
  }
174
 
175
  static function auto_generate() {
176
- global $redirection;
177
-
178
- $options = $redirection->get_options();
179
  $id = time();
180
 
181
  $url = $options['auto_target'];
@@ -379,7 +377,7 @@ class Red_Item {
379
  elseif ( isset( $_SERVER['REMOTE_ADDR'] ) )
380
  $ip = $_SERVER['REMOTE_ADDR'];
381
 
382
- $options = $redirection->get_options();
383
  if ( isset( $options['expire_redirect'] ) && $options['expire_redirect'] >= 0 )
384
  $log = RE_Log::create( $url, $target, $_SERVER['HTTP_USER_AGENT'], $ip, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '', array( 'redirect_id' => $this->id, 'module_id' => $this->module_id, 'group_id' => $this->group_id) );
385
  }
173
  }
174
 
175
  static function auto_generate() {
176
+ $options = red_get_options();
 
 
177
  $id = time();
178
 
179
  $url = $options['auto_target'];
377
  elseif ( isset( $_SERVER['REMOTE_ADDR'] ) )
378
  $ip = $_SERVER['REMOTE_ADDR'];
379
 
380
+ $options = red_get_options();
381
  if ( isset( $options['expire_redirect'] ) && $options['expire_redirect'] >= 0 )
382
  $log = RE_Log::create( $url, $target, $_SERVER['HTTP_USER_AGENT'], $ip, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '', array( 'redirect_id' => $this->id, 'module_id' => $this->module_id, 'group_id' => $this->group_id) );
383
  }
modules/wordpress.php CHANGED
@@ -1,37 +1,32 @@
1
  <?php
2
 
3
  class WordPress_Module extends Red_Module {
4
- var $canonical = 'default';
5
- var $strip_index = 'default';
6
- var $time_limit = 0;
7
- var $matched;
8
 
9
- function start() {
10
- // Setup the various filters and actions that allow Redirection to h appen
11
  add_action( 'init', array( &$this, 'init' ) );
12
  add_action( 'send_headers', array( &$this, 'send_headers' ) );
13
  add_filter( 'permalink_redirect_skip', array( &$this, 'permalink_redirect_skip' ) );
14
  add_filter( 'wp_redirect', array( &$this, 'wp_redirect' ), 1, 2 );
 
15
 
16
  // Remove WordPress 2.3 redirection
17
  remove_action( 'template_redirect', 'wp_old_slug_redirect' );
18
  remove_action( 'edit_form_advanced', 'wp_remember_old_slug' );
19
  }
20
 
21
- function init() {
22
- global $redirection;
23
-
24
  $url = $_SERVER['REQUEST_URI'];
25
 
26
  // Make sure we don't try and redirect something essential
27
- if ( !$this->protected_url( $url ) && !$redirection->hasMatched() ) {
28
  do_action( 'redirection_first', $url, $this );
29
 
30
  $redirects = Red_Item::get_for_url( $url, 'wp' );
31
 
32
  foreach ( (array)$redirects AS $item ) {
33
  if ( $item->matches( $url ) ) {
34
- $redirection->setMatched( true );
35
  $this->matched = $item;
36
  break;
37
  }
@@ -41,28 +36,38 @@ class WordPress_Module extends Red_Module {
41
  }
42
  }
43
 
44
- function protected_url( $url ) {
45
  return false;
46
  }
47
 
48
- function status_header( $status ) {
 
 
 
 
 
 
 
 
 
 
49
  // Fix for incorrect headers sent when using FastCGI/IIS
50
  if ( substr( php_sapi_name(), 0, 3 ) == 'cgi' )
51
  return str_replace( 'HTTP/1.1', 'Status:', $status );
52
  return $status;
53
  }
54
 
55
- function send_headers( $obj ) {
56
  if ( !empty( $this->matched ) && $this->matched->match->action_code == '410' ) {
57
  add_filter( 'status_header', array( &$this, 'set_header_410' ) );
58
  }
59
  }
60
 
61
- function set_header_410() {
62
  return 'HTTP/1.1 410 Gone';
63
  }
64
 
65
- function wp_redirect( $url, $status ) {
66
  global $wp_version, $is_IIS;
67
 
68
  if ( $is_IIS ) {
@@ -84,25 +89,25 @@ class WordPress_Module extends Red_Module {
84
  return $url;
85
  }
86
 
87
- function save( $data ) {
88
  return array();
89
  }
90
 
91
- function permalink_redirect_skip( $skip ) {
92
- // only want this if we:ve matched using redirection
93
  if ( $this->matched )
94
  $skip[] = $_SERVER['REQUEST_URI'];
95
  return $skip;
96
  }
97
 
98
- function is_valid() {
99
  $perm = get_option( 'permalink_structure' );
100
  if ( $perm === false || $perm == '' )
101
  return false;
102
  return true;
103
  }
104
 
105
- function options() {
106
  if ( !$this->is_valid() )
107
  echo __( '<strong>Disabled: You must enable <a href="options-permalink.php">permalinks</a> before using this</strong>', 'redirection' );
108
  }
@@ -110,4 +115,30 @@ class WordPress_Module extends Red_Module {
110
  public function get_type_string() {
111
  return __( 'WordPress', 'redirection' );
112
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
113
  }
1
  <?php
2
 
3
  class WordPress_Module extends Red_Module {
4
+ private $matched = false;
 
 
 
5
 
6
+ public function start() {
7
+ // Setup the various filters and actions that allow Redirection to happen
8
  add_action( 'init', array( &$this, 'init' ) );
9
  add_action( 'send_headers', array( &$this, 'send_headers' ) );
10
  add_filter( 'permalink_redirect_skip', array( &$this, 'permalink_redirect_skip' ) );
11
  add_filter( 'wp_redirect', array( &$this, 'wp_redirect' ), 1, 2 );
12
+ add_action( 'template_redirect', array( &$this, 'template_redirect' ) );
13
 
14
  // Remove WordPress 2.3 redirection
15
  remove_action( 'template_redirect', 'wp_old_slug_redirect' );
16
  remove_action( 'edit_form_advanced', 'wp_remember_old_slug' );
17
  }
18
 
19
+ public function init() {
 
 
20
  $url = $_SERVER['REQUEST_URI'];
21
 
22
  // Make sure we don't try and redirect something essential
23
+ if ( !$this->protected_url( $url ) && $this->matched === false ) {
24
  do_action( 'redirection_first', $url, $this );
25
 
26
  $redirects = Red_Item::get_for_url( $url, 'wp' );
27
 
28
  foreach ( (array)$redirects AS $item ) {
29
  if ( $item->matches( $url ) ) {
 
30
  $this->matched = $item;
31
  break;
32
  }
36
  }
37
  }
38
 
39
+ private function protected_url( $url ) {
40
  return false;
41
  }
42
 
43
+ public function template_redirect() {
44
+ if ( is_404() ) {
45
+ $options = red_get_options();
46
+
47
+ if ( isset( $options['expire_404'] ) && $options['expire_404'] >= 0 ) {
48
+ RE_404::create( $this->get_url(), $this->get_user_agent(), $this->get_ip(), $this->get_referrer() );
49
+ }
50
+ }
51
+ }
52
+
53
+ public function status_header( $status ) {
54
  // Fix for incorrect headers sent when using FastCGI/IIS
55
  if ( substr( php_sapi_name(), 0, 3 ) == 'cgi' )
56
  return str_replace( 'HTTP/1.1', 'Status:', $status );
57
  return $status;
58
  }
59
 
60
+ public function send_headers( $obj ) {
61
  if ( !empty( $this->matched ) && $this->matched->match->action_code == '410' ) {
62
  add_filter( 'status_header', array( &$this, 'set_header_410' ) );
63
  }
64
  }
65
 
66
+ public function set_header_410() {
67
  return 'HTTP/1.1 410 Gone';
68
  }
69
 
70
+ public function wp_redirect( $url, $status ) {
71
  global $wp_version, $is_IIS;
72
 
73
  if ( $is_IIS ) {
89
  return $url;
90
  }
91
 
92
+ public function save( $data ) {
93
  return array();
94
  }
95
 
96
+ public function permalink_redirect_skip( $skip ) {
97
+ // only want this if we've matched using redirection
98
  if ( $this->matched )
99
  $skip[] = $_SERVER['REQUEST_URI'];
100
  return $skip;
101
  }
102
 
103
+ public function is_valid() {
104
  $perm = get_option( 'permalink_structure' );
105
  if ( $perm === false || $perm == '' )
106
  return false;
107
  return true;
108
  }
109
 
110
+ public function options() {
111
  if ( !$this->is_valid() )
112
  echo __( '<strong>Disabled: You must enable <a href="options-permalink.php">permalinks</a> before using this</strong>', 'redirection' );
113
  }
115
  public function get_type_string() {
116
  return __( 'WordPress', 'redirection' );
117
  }
118
+
119
+ private function get_url() {
120
+ if ( isset( $_SERVER['REQUEST_URI'] ) )
121
+ return $_SERVER['REQUEST_URI'];
122
+ return '';
123
+ }
124
+
125
+ private function get_user_agent() {
126
+ if ( isset( $_SERVER['HTTP_USER_AGENT'] ) )
127
+ return $_SERVER['HTTP_USER_AGENT'];
128
+ return false;
129
+ }
130
+
131
+ private function get_referrer() {
132
+ if ( isset( $_SERVER['HTTP_REFERER'] ) )
133
+ return $_SERVER['HTTP_REFERER'];
134
+ return false;
135
+ }
136
+
137
+ private function get_ip() {
138
+ if ( isset( $_SERVER['REMOTE_ADDR'] ) )
139
+ return $_SERVER['REMOTE_ADDR'];
140
+ elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
141
+ return $_SERVER['HTTP_X_FORWARDED_FOR'];
142
+ return '';
143
+ }
144
  }
readme.txt CHANGED
@@ -2,9 +2,9 @@
2
  Contributors: johnny5
3
  Donate link: http://urbangiraffe.com/about/
4
  Tags: post, admin, seo, pages, manage, 301, 404, redirect, permalink
5
- Requires at least: 3.2
6
  Tested up to: 4.2
7
- Stable tag: 2.3.12
8
 
9
  Redirection is a WordPress plugin to manage 301 redirections and keep track of 404 errors without requiring knowledge of Apache .htaccess files.
10
 
@@ -54,12 +54,12 @@ Redirection is available in:
54
  * Dutch by Marlon Navas, Pieter Carette, and Bart Kummel
55
  * Hungarian by daSSad and Szépe Viktor
56
  * Turkish by Fatih Cevik
57
- * Romanian translation, thanks to InboxTranslations
58
- * Greek, thanks to Stefanos Kofopoulos
59
- * Belarusian, thanks to Alexander Ovsov
60
- * Czech, thanks to Martin Jurica
61
- * Danish, thanks to Rasmus Himmelstrup
62
- * Persian, thanks to Danial Hatami
63
 
64
  Please submit bugs and patches to https://github.com/johngodley/redirection
65
 
@@ -94,13 +94,20 @@ The plugin works in a similar manner to how WordPress handles permalinks and sho
94
 
95
  == Changelog ==
96
 
 
 
 
 
 
 
97
  = 2.3.12 =
98
  * Persian translation by Danial Hatami
99
- * Fix saving a redirection by login status, referrer, and user agent
100
  * Fix problem where deleting your last group would cause Redirection to only show an error
101
  * Add limits to referrer and destination in the logs
102
  * Redirect title now shows in the main list again. The field is hidden when editing until toggled
103
  * Fix 'bad nonce' error, props to Jonathan Harrell
 
104
 
105
  = 2.3.11 =
106
  * Fix log cleanup options
2
  Contributors: johnny5
3
  Donate link: http://urbangiraffe.com/about/
4
  Tags: post, admin, seo, pages, manage, 301, 404, redirect, permalink
5
+ Requires at least: 3.4
6
  Tested up to: 4.2
7
+ Stable tag: 2.3.13
8
 
9
  Redirection is a WordPress plugin to manage 301 redirections and keep track of 404 errors without requiring knowledge of Apache .htaccess files.
10
 
54
  * Dutch by Marlon Navas, Pieter Carette, and Bart Kummel
55
  * Hungarian by daSSad and Szépe Viktor
56
  * Turkish by Fatih Cevik
57
+ * Romanian by InboxTranslations
58
+ * Greek by Stefanos Kofopoulos
59
+ * Belarusian by Alexander Ovsov
60
+ * Czech by Martin Jurica
61
+ * Danish by Rasmus Himmelstrup
62
+ * Persian by Danial Hatami
63
 
64
  Please submit bugs and patches to https://github.com/johngodley/redirection
65
 
94
 
95
  == Changelog ==
96
 
97
+ = 2.3.13 =
98
+ * Split admin and front-end code out to streamline the loading a bit
99
+ * Fix bad groups link when viewing redirects in a group, props to Patrick Fabre
100
+ * Improved plugin activation/deactivation and cleanup
101
+ * Improved log clearing
102
+
103
  = 2.3.12 =
104
  * Persian translation by Danial Hatami
105
+ * Fix saving a redirection with login status, referrer, and user agent
106
  * Fix problem where deleting your last group would cause Redirection to only show an error
107
  * Add limits to referrer and destination in the logs
108
  * Redirect title now shows in the main list again. The field is hidden when editing until toggled
109
  * Fix 'bad nonce' error, props to Jonathan Harrell
110
+ * Remove old WP code
111
 
112
  = 2.3.11 =
113
  * Fix log cleanup options
redirection-admin.php ADDED
@@ -0,0 +1,504 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ include dirname( __FILE__ ).'/models/group.php';
4
+ include dirname( __FILE__ ).'/models/monitor.php';
5
+ include dirname( __FILE__ ).'/models/pager.php';
6
+ include dirname( __FILE__ ).'/models/file_io.php';
7
+
8
+ class Redirection_Admin {
9
+ private static $instance = null;
10
+ private $monitor;
11
+
12
+ static function init() {
13
+ if ( is_null( self::$instance ) ) {
14
+ self::$instance = new Redirection_Admin();
15
+
16
+ load_plugin_textdomain( 'redirection', false, dirname( plugin_basename( REDIRECTION_FILE ) ).'/locale/' );
17
+ }
18
+
19
+ return self::$instance;
20
+ }
21
+
22
+ function __construct() {
23
+ add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
24
+ add_action( 'load-tools_page_redirection', array( &$this, 'redirection_head' ) );
25
+ add_action( 'plugin_action_links_'.basename( dirname( REDIRECTION_FILE ) ).'/'.basename( REDIRECTION_FILE ), array( &$this, 'plugin_settings' ), 10, 4 );
26
+
27
+ add_filter( 'set-screen-option', array( $this, 'set_per_page' ), 10, 3 );
28
+
29
+ register_deactivation_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_deactivated' ) );
30
+ register_uninstall_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_uninstall' ) );
31
+
32
+ add_action( 'wp_ajax_red_log_delete', array( &$this, 'ajax_log_delete' ) );
33
+ add_action( 'wp_ajax_red_module_edit', array( &$this, 'ajax_module_edit' ) );
34
+ add_action( 'wp_ajax_red_module_save', array( &$this, 'ajax_module_save' ) );
35
+ add_action( 'wp_ajax_red_group_edit', array( &$this, 'ajax_group_edit' ) );
36
+ add_action( 'wp_ajax_red_group_save', array( &$this, 'ajax_group_save' ) );
37
+ add_action( 'wp_ajax_red_redirect_add', array( &$this, 'ajax_redirect_add' ) );
38
+ add_action( 'wp_ajax_red_redirect_edit', array( &$this, 'ajax_redirect_edit' ) );
39
+ add_action( 'wp_ajax_red_redirect_save', array( &$this, 'ajax_redirect_save' ) );
40
+
41
+ $this->monitor = new Red_Monitor( red_get_options() );
42
+ }
43
+
44
+ public static function plugin_activated() {
45
+ Red_Flusher::schedule();
46
+ }
47
+
48
+ public static function plugin_deactivated() {
49
+ Red_Flusher::clear();
50
+ }
51
+
52
+ public static function plugin_uninstall() {
53
+ include dirname( REDIRECTION_FILE ).'/models/database.php';
54
+
55
+ $db = new RE_Database();
56
+ $db->remove( REDIRECTION_FILE );
57
+ }
58
+
59
+ private function render( $template, $template_vars = array() ) {
60
+ foreach ( $template_vars AS $key => $val ) {
61
+ $$key = $val;
62
+ }
63
+
64
+ if ( file_exists( dirname( REDIRECTION_FILE )."/view/admin/$template.php" ) )
65
+ include dirname( REDIRECTION_FILE )."/view/admin/$template.php";
66
+ }
67
+
68
+ private function capture( $ug_name, $ug_vars = array() ) {
69
+ ob_start();
70
+
71
+ $this->render( $ug_name, $ug_vars );
72
+ $output = ob_get_contents();
73
+
74
+ ob_end_clean();
75
+ return $output;
76
+ }
77
+
78
+ private function render_error( $message ) {
79
+ ?>
80
+ <div class="fade error" id="message">
81
+ <p><?php echo $message ?></p>
82
+ </div>
83
+ <?php
84
+ }
85
+
86
+ private function render_message( $message, $timeout = 0 ) {
87
+ ?>
88
+ <div class="updated" id="message" onclick="this.parentNode.removeChild(this)">
89
+ <p><?php echo $message ?></p>
90
+ </div>
91
+ <?php
92
+ }
93
+
94
+ private function update() {
95
+ $version = get_option( 'redirection_version' );
96
+
97
+ if ( $version != REDIRECTION_VERSION ) {
98
+ include_once dirname( REDIRECTION_FILE ).'/models/database.php';
99
+
100
+ $database = new RE_Database();
101
+ return $database->upgrade( $version, REDIRECTION_VERSION );
102
+ }
103
+
104
+ return true;
105
+ }
106
+
107
+ private function select( $items, $default = '' ) {
108
+ foreach ( $items AS $key => $value ) {
109
+ if ( is_array( $value ) ) {
110
+ echo '<optgroup label="'.esc_attr( $key ).'">';
111
+
112
+ foreach ( $value AS $sub => $subvalue ) {
113
+ echo '<option value="'.esc_attr( $sub ).'"'.( $sub == $default ? ' selected="selected"' : '' ).'>'.esc_html( $subvalue ).'</option>';
114
+ }
115
+
116
+ echo '</optgroup>';
117
+ }
118
+ else
119
+ echo '<option value="'.esc_attr( $key ).'"'.( $key == $default ? ' selected="selected"' : '' ).'>'.esc_html( $value ).'</option>';
120
+ }
121
+ }
122
+
123
+ function set_per_page( $status, $option, $value ) {
124
+ if ( $option == 'redirection_log_per_page' )
125
+ return $value;
126
+ return $status;
127
+ }
128
+
129
+ function plugin_settings( $links ) {
130
+ $settings_link = '<a href="tools.php?page='.basename( REDIRECTION_FILE ).'&amp;sub=options">'.__( 'Settings', 'redirection' ).'</a>';
131
+ array_unshift( $links, $settings_link );
132
+ return $links;
133
+ }
134
+
135
+ function redirection_head() {
136
+ $version = get_plugin_data( REDIRECTION_FILE );
137
+ $version = $version['Version'];
138
+
139
+ $this->inject();
140
+
141
+ if ( !isset( $_GET['sub'] ) || ( isset( $_GET['sub'] ) && ( in_array( $_GET['sub'], array( 'log', '404s', 'groups' ) ) ) ) )
142
+ add_screen_option( 'per_page', array( 'label' => __( 'Log entries', 'redirection' ), 'default' => 25, 'option' => 'redirection_log_per_page' ) );
143
+
144
+ wp_enqueue_script( 'redirection', plugin_dir_url( REDIRECTION_FILE ).'redirection.js', array( 'jquery-form', 'jquery-ui-sortable' ), $version );
145
+ wp_enqueue_style( 'redirection', plugin_dir_url( REDIRECTION_FILE ).'admin.css', $version );
146
+
147
+ wp_localize_script( 'redirection', 'Redirectioni10n', array(
148
+ 'error_msg' => __( 'Sorry, unable to do that. Please try refreshing the page.' ),
149
+ ) );
150
+ }
151
+
152
+ function admin_menu() {
153
+ add_management_page( __( "Redirection", 'redirection' ), __( "Redirection", 'redirection' ), apply_filters( 'redirection_role', 'administrator' ), basename( REDIRECTION_FILE ), array( &$this, "admin_screen" ) );
154
+ }
155
+
156
+ function admin_screen() {
157
+ $this->update();
158
+
159
+ if ( isset($_GET['sub']) ) {
160
+ if ( $_GET['sub'] == 'log' )
161
+ return $this->admin_screen_log();
162
+ elseif ( $_GET['sub'] == '404s' )
163
+ return $this->admin_screen_404();
164
+ elseif ( $_GET['sub'] == 'options' )
165
+ return $this->admin_screen_options();
166
+ elseif ( $_GET['sub'] == 'process' )
167
+ return $this->admin_screen_process();
168
+ elseif ( $_GET['sub'] == 'groups' )
169
+ return $this->admin_groups( isset( $_GET['id'] ) ? intval( $_GET['id'] ) : 0 );
170
+ elseif ( $_GET['sub'] == 'modules' )
171
+ return $this->admin_screen_modules();
172
+ elseif ( $_GET['sub'] == 'support' )
173
+ return $this->render('support', array( 'options' => red_get_options() ) );
174
+ }
175
+
176
+ return $this->admin_redirects( isset( $_GET['id'] ) ? intval( $_GET['id'] ) : 0 );
177
+ }
178
+
179
+ function admin_screen_modules() {
180
+ $options = red_get_options();
181
+ $pager = new Redirection_Module_Table( $options['token'] );
182
+ $pager->prepare_items();
183
+
184
+ $this->render( 'module_list', array( 'options' => $options, 'table' => $pager ) );
185
+ }
186
+
187
+ function inject() {
188
+ $options = red_get_options();
189
+
190
+ if ( isset( $_POST['id'] ) && !isset( $_POST['action'] ) ) {
191
+ wp_safe_redirect( add_query_arg( 'id', intval( $_POST['id'] ), $_SERVER['REQUEST_URI'] ) );
192
+ die();
193
+ }
194
+
195
+ if ( isset( $_GET['token'] ) && isset( $_GET['page'] ) && isset( $_GET['sub'] ) && $_GET['token'] == $options['token'] && $_GET['page'] == 'redirection.php' ) {
196
+ $exporter = Red_FileIO::create( $_GET['sub'] );
197
+ if ( $exporter ) {
198
+ $items = Red_Item::get_all_for_module( intval( $_GET['module'] ) );
199
+
200
+ $exporter->export( $items );
201
+ die();
202
+ }
203
+ }
204
+ elseif ( isset( $_POST['export-csv'] ) && check_admin_referer( 'redirection-log_management' ) ) {
205
+ if ( isset( $_GET['sub'] ) && $_GET['sub'] == 'log' )
206
+ RE_Log::export_to_csv();
207
+ else
208
+ RE_404::export_to_csv();
209
+ die();
210
+ }
211
+ }
212
+
213
+ function admin_screen_options() {
214
+ if ( isset( $_POST['regenerate'] ) && check_admin_referer( 'redirection-update_options' ) ) {
215
+ $options = red_get_options();
216
+ $options['token'] = md5( uniqid() );
217
+
218
+ update_option( 'redirection_options', $options );
219
+
220
+ $this->render_message( __( 'Your options were updated', 'redirection' ) );
221
+ }
222
+ elseif ( isset( $_POST['update'] ) && check_admin_referer( 'redirection-update_options' ) ) {
223
+ $options['monitor_post'] = stripslashes( $_POST['monitor_post'] );
224
+ $options['auto_target'] = stripslashes( $_POST['auto_target'] );
225
+ $options['support'] = isset( $_POST['support'] ) ? true : false;
226
+ $options['token'] = stripslashes( $_POST['token'] );
227
+ $options['expire_redirect'] = min( intval( $_POST['expire_redirect'] ), 60 );
228
+ $options['expire_404'] = min( intval( $_POST['expire_404'] ), 60 );
229
+
230
+ if ( trim( $options['token'] ) == '' )
231
+ $options['token'] = md5( uniqid() );
232
+
233
+ update_option( 'redirection_options', $options );
234
+
235
+ Red_Flusher::schedule();
236
+ $this->render_message( __( 'Your options were updated', 'redirection' ) );
237
+ }
238
+ elseif ( isset( $_POST['delete'] ) && check_admin_referer( 'redirection-delete_plugin' ) ) {
239
+ $this->plugin_uninstall();
240
+
241
+ $current = get_option( 'active_plugins' );
242
+ array_splice( $current, array_search( basename( dirname( REDIRECTION_FILE ) ).'/'.basename( REDIRECTION_FILE ), $current ), 1 );
243
+ update_option( 'active_plugins', $current );
244
+
245
+ $this->render_message( __( 'Redirection data has been deleted and the plugin disabled', 'redirection' ) );
246
+ return;
247
+ }
248
+ elseif ( isset( $_POST['import'] ) && check_admin_referer( 'redirection-import' ) ) {
249
+ $count = Red_FileIO::import( $_POST['group'], $_FILES['upload'] );
250
+
251
+ if ( $count > 0 )
252
+ $this->render_message( sprintf( _n( '%d redirection was successfully imported','%d redirections were successfully imported', $count, 'redirection' ), $count ) );
253
+ else
254
+ $this->render_message( __( 'No items were imported', 'redirection' ) );
255
+ }
256
+
257
+ $groups = Red_Group::get_for_select();
258
+ $this->render( 'options', array( 'options' => red_get_options(), 'groups' => $groups ) );
259
+ }
260
+
261
+ function admin_screen_log() {
262
+ $options = red_get_options();
263
+
264
+ if ( isset( $_POST['delete-all'] ) && check_admin_referer( 'redirection-log_management' ) ) {
265
+ RE_Log::delete_all();
266
+ $this->render_message( __( 'Your logs have been deleted', 'redirection' ) );
267
+ }
268
+
269
+ $table = new Redirection_Log_Table( $options );
270
+
271
+ if ( isset( $_GET['module'] ) )
272
+ $table->prepare_items( 'module', intval( $_GET['module'] ) );
273
+ else if (isset($_GET['group']))
274
+ $table->prepare_items( 'group', intval( $_GET['group'] ) );
275
+ else if (isset($_GET['redirect']))
276
+ $table->prepare_items( 'redirect', intval( $_GET['redirect'] ) );
277
+ else
278
+ $table->prepare_items();
279
+
280
+ $this->render( 'log', array( 'options' => $options, 'table' => $table, 'lookup' => $options['lookup'], 'type' => 'log' ) );
281
+ }
282
+
283
+ function admin_screen_404() {
284
+ if ( isset( $_POST['delete-all'] ) && check_admin_referer( 'redirection-log_management' ) ) {
285
+ RE_404::delete_all();
286
+ $this->render_message( __( 'Your logs have been deleted', 'redirection' ) );
287
+ }
288
+
289
+ $options = red_get_options();
290
+
291
+ $table = new Redirection_404_Table( $options );
292
+ $table->prepare_items( isset( $_GET['ip'] ) ? $_GET['ip'] : false );
293
+
294
+ $this->render( 'log', array( 'options' => $options, 'table' => $table, 'lookup' => $options['lookup'], 'type' => '404s' ) );
295
+ }
296
+
297
+ function admin_groups( $module ) {
298
+ if ( isset( $_POST['add'] ) && check_admin_referer( 'redirection-add_group' ) ) {
299
+ if ( Red_Group::create( stripslashes_deep( $_POST ) ) ) {
300
+ $this->render_message( __( 'Your group was added successfully', 'redirection' ) );
301
+ Red_Module::flush( $module );
302
+ }
303
+ else
304
+ $this->render_error( __( 'Please specify a group name', 'redirection' ) );
305
+ }
306
+
307
+ if ( $module == 0 )
308
+ $module = Red_Module::get_first_id();
309
+
310
+ $table = new Redirection_Group_Table( Red_Module::get_for_select(), $module );
311
+ $table->prepare_items();
312
+
313
+ $module = Red_Module::get( $module );
314
+ if ( $module )
315
+ $this->render( 'group_list', array( 'options' => red_get_options(), 'table' => $table, 'modules' => Red_Module::get_for_select(), 'module' => $module ) );
316
+ else
317
+ $this->render_message( __( 'Unknown module', 'redirection' ) );
318
+ }
319
+
320
+ function admin_redirects( $group_id ) {
321
+ if ( $group_id == 0 )
322
+ $group_id = Red_Group::get_first_id();
323
+
324
+ $group = Red_Group::get( $group_id );
325
+ if ( $group === false ) {
326
+ $group = Red_Group::create( array( 'name' => 'Redirections', 'module_id' => 1 ) );
327
+ }
328
+
329
+ $table = new Redirection_Table( Red_Group::get_for_select(), $group );
330
+ $table->prepare_items();
331
+
332
+ $this->render( 'item_list', array( 'options' => red_get_options(), 'group' => $group, 'table' => $table, 'date_format' => get_option( 'date_format' ) ) );
333
+ }
334
+
335
+ function locales() {
336
+ $locales = array();
337
+ if ( file_exists( dirname( REDIRECTION_FILE ).'/readme.txt' ) ) {
338
+ $readme = file_get_contents( dirname( REDIRECTION_FILE ).'/readme.txt' );
339
+
340
+ $start = strpos( $readme, 'Redirection is available in' );
341
+ $end = strpos( $readme, '==', $start );
342
+ if ( $start !== false && $end !== false ) {
343
+ if ( preg_match_all( '/^\* (.*?) by (.*?)/m', substr( $readme, $start, $end ), $matches ) > 0 ) {
344
+ $locales = $matches[1];
345
+ }
346
+ }
347
+
348
+ sort( $locales );
349
+ }
350
+
351
+ return $locales;
352
+ }
353
+
354
+ public function ajax_log_delete() {
355
+ if ( check_ajax_referer( 'redirection-items' ) ) {
356
+ if ( preg_match_all( '/=(\d*)/', $_POST['checked'], $items ) > 0) {
357
+ foreach ( $items[1] AS $item ) {
358
+ RE_Log::delete( intval( $item ) );
359
+ }
360
+ }
361
+ }
362
+ }
363
+
364
+ private function check_ajax_referer( $nonce ) {
365
+ if ( check_ajax_referer( $nonce, false, false ) === false )
366
+ $this->output_ajax_response( array( 'error' => __( 'Unable to perform action' ).' - bad nonce' ) );
367
+ }
368
+
369
+ public function ajax_module_edit() {
370
+ $module_id = intval( $_POST['id'] );
371
+
372
+ $this->check_ajax_referer( 'red_edit-'.$module_id );
373
+
374
+ $module = Red_Module::get( $module_id );
375
+ if ( $module )
376
+ $json['html'] = $this->capture( 'module_edit', array( 'module' => $module ) );
377
+ else
378
+ $json['error'] = __( 'Unable to perform action' ).' - could not find module';
379
+
380
+ $this->output_ajax_response( $json );
381
+ }
382
+
383
+ public function ajax_module_save() {
384
+ global $hook_suffix;
385
+
386
+ $hook_suffix = '';
387
+ $module_id = intval( $_POST['id'] );
388
+ $options = red_get_options();
389
+
390
+ $this->check_ajax_referer( 'red_module_save_'.$module_id );
391
+
392
+ $module = Red_Module::get( $module_id );
393
+
394
+ if ( $module ) {
395
+ $module->update( $_POST );
396
+
397
+ $pager = new Redirection_Module_Table( $options['token'] );
398
+ $json = array( 'html' => $pager->column_name( $module ) );
399
+ }
400
+ else
401
+ $json['error'] = __( 'Unable to perform action' ).' - could not find module';
402
+
403
+ $this->output_ajax_response( $json );
404
+ }
405
+
406
+ public function ajax_group_edit() {
407
+ $group_id = intval( $_POST['id'] );
408
+
409
+ $this->check_ajax_referer( 'red-edit_'.$group_id );
410
+
411
+ $group = Red_Group::get( $group_id );
412
+ if ( $group )
413
+ $json['html'] = $this->capture( 'group_edit', array( 'group' => $group, 'modules' => Red_Module::get_for_select() ) );
414
+ else
415
+ $json['error'] = __( 'Unable to perform action' ).' - could not find group';
416
+
417
+ $this->output_ajax_response( $json );
418
+ }
419
+
420
+ public function ajax_group_save() {
421
+ global $hook_suffix;
422
+
423
+ $hook_suffix = '';
424
+ $group_id = intval( $_POST['id'] );
425
+
426
+ $this->check_ajax_referer( 'redirection-group_save_'.$group_id );
427
+
428
+ $group = Red_Group::get( $group_id );
429
+ if ( $group ) {
430
+ $group->update( $_POST );
431
+
432
+ $pager = new Redirection_Group_Table( array(), false );
433
+ $json = array( 'html' => $pager->column_name( $group ) );
434
+ }
435
+ else
436
+ $json['error'] = __( 'Unable to perform action' ).' - could not find redirect';
437
+
438
+ $this->output_ajax_response( $json );
439
+ }
440
+
441
+ public function ajax_redirect_edit() {
442
+ $this->check_ajax_referer( 'red-edit_'.intval( $_POST['id'] ) );
443
+ $redirect = Red_Item::get_by_id( intval( $_POST['id'] ) );
444
+
445
+ if ( $redirect )
446
+ $json['html'] = $this->capture( 'item_edit', array( 'redirect' => $redirect, 'groups' => Red_Group::get_for_select() ) );
447
+ else
448
+ $json['error'] = __( 'Unable to perform action' ).' - could not find redirect';
449
+
450
+ $this->output_ajax_response( $json );
451
+ }
452
+
453
+ public function ajax_redirect_save() {
454
+ global $hook_suffix;
455
+
456
+ $hook_suffix = '';
457
+
458
+ $red_id = intval( $_POST['id'] );
459
+
460
+ $this->check_ajax_referer( 'redirection-redirect_save_'.$red_id );
461
+
462
+ $redirect = Red_Item::get_by_id( $red_id );
463
+ if ( $redirect ) {
464
+ $redirect->update( $_POST );
465
+
466
+ $pager = new Redirection_Table( array() );
467
+ $json = array( 'html' => $pager->column_url( $redirect ), 'code' => $redirect->get_action_code() );
468
+ }
469
+ else
470
+ $json['error'] = __( 'Unable to perform action' ).' - could not find redirect';
471
+
472
+ $this->output_ajax_response( $json );
473
+ }
474
+
475
+ public function ajax_redirect_add() {
476
+ global $hook_suffix;
477
+
478
+ $hook_suffix = '';
479
+
480
+ $this->check_ajax_referer( 'redirection-redirect_add' );
481
+
482
+ $item = Red_Item::create( $_POST );
483
+ if ( is_wp_error( $item ) )
484
+ $json['error'] = $item->get_error_message();
485
+ elseif ( $item !== false ) {
486
+ $pager = new Redirection_Table( array() );
487
+ $json = array( 'html' => $pager->get_row( $item ) );
488
+ }
489
+ else
490
+ $json['error'] = __( 'Sorry, but your redirection was not created', 'redirection' );
491
+
492
+ $this->output_ajax_response( $json );
493
+ }
494
+
495
+ private function output_ajax_response( array $data ) {
496
+ header( 'Content-Type: application/json' );
497
+ echo json_encode( $data );
498
+ die();
499
+ }
500
+ }
501
+
502
+ register_activation_hook( REDIRECTION_FILE, array( 'Redirection_Admin', 'plugin_activated' ) );
503
+
504
+ add_action( 'init', array( 'Redirection_Admin', 'init' ) );
redirection-front.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ include dirname( __FILE__ ).'/modules/wordpress.php';
4
+
5
+ class Redirection {
6
+ private static $instance = null;
7
+ private $module;
8
+
9
+ static function init() {
10
+ if ( is_null( self::$instance ) ) {
11
+ self::$instance = new Redirection();
12
+ }
13
+
14
+ return self::$instance;
15
+ }
16
+
17
+ public function __construct() {
18
+ $this->module = new WordPress_Module();
19
+ $this->module->start();
20
+
21
+ add_action( Red_Flusher::DELETE_HOOK, array( $this, 'clean_redirection_logs' ) );
22
+ }
23
+
24
+ public function clean_redirection_logs() {
25
+ $flusher = new Red_Flusher();
26
+ $flusher->flush();
27
+ }
28
+ }
29
+
30
+ add_action( 'plugins_loaded', array( 'Redirection', 'init' ) );
redirection.js CHANGED
@@ -185,6 +185,7 @@ var Redirection;
185
  if ( add_to_screen === true ) {
186
  $( add_form ).addClass( 'loaded' );
187
 
 
188
  $( 'table.items' ).append( response.html );
189
  $( 'table.items tr' ).each( function( pos, item ) {
190
  $( item ).removeClass( 'alternate' );
185
  if ( add_to_screen === true ) {
186
  $( add_form ).addClass( 'loaded' );
187
 
188
+ $( 'table tr.no-items' ).remove();
189
  $( 'table.items' ).append( response.html );
190
  $( 'table.items tr' ).each( function( pos, item ) {
191
  $( item ).removeClass( 'alternate' );
redirection.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: Redirection
4
  Plugin URI: http://urbangiraffe.com/plugins/redirection/
5
  Description: Manage all your 301 redirects and monitor 404 errors
6
- Version: 2.3.12
7
  Author: John Godley
8
  Author URI: http://urbangiraffe.com
9
  ============================================================================================================
@@ -19,631 +19,40 @@ For full license details see license.txt
19
  ============================================================================================================
20
  */
21
 
22
- include dirname( __FILE__ ).'/models/redirect.php';
23
- include dirname( __FILE__ ).'/models/match.php';
24
- include dirname( __FILE__ ).'/models/log.php';
25
- include dirname( __FILE__ ).'/models/group.php';
26
- include dirname( __FILE__ ).'/models/module.php';
27
- include dirname( __FILE__ ).'/models/action.php';
28
- include dirname( __FILE__ ).'/models/monitor.php';
29
- include dirname( __FILE__ ).'/modules/wordpress.php';
30
-
31
  define( 'REDIRECTION_VERSION', '2.3.1' ); // DB schema version. Only change if DB needs changing
 
32
 
33
- class Redirection {
34
- var $hasMatched = false;
35
-
36
- function __construct() {
37
- if ( is_admin() ) {
38
- add_action( 'admin_menu', array( &$this, 'admin_menu' ) );
39
- add_action( 'init', array( &$this, 'init' ) );
40
- add_action( 'load-tools_page_redirection', array( &$this, 'redirection_head' ) );
41
-
42
- add_filter( 'set-screen-option', array( $this, 'set_per_page' ), 10, 3 );
43
-
44
- add_action( 'plugin_action_links_'.basename( dirname( __FILE__ ) ).'/'.basename( __FILE__ ), array( &$this, 'plugin_settings' ), 10, 4 );
45
-
46
- add_action( 'wp_ajax_red_log_delete', array( &$this, 'ajax_log_delete' ) );
47
- add_action( 'wp_ajax_red_module_edit', array( &$this, 'ajax_module_edit' ) );
48
- add_action( 'wp_ajax_red_module_save', array( &$this, 'ajax_module_save' ) );
49
- add_action( 'wp_ajax_red_group_edit', array( &$this, 'ajax_group_edit' ) );
50
- add_action( 'wp_ajax_red_group_save', array( &$this, 'ajax_group_save' ) );
51
- add_action( 'wp_ajax_red_redirect_add', array( &$this, 'ajax_redirect_add' ) );
52
- add_action( 'wp_ajax_red_redirect_edit', array( &$this, 'ajax_redirect_edit' ) );
53
- add_action( 'wp_ajax_red_redirect_save', array( &$this, 'ajax_redirect_save' ) );
54
-
55
- $this->update();
56
- }
57
- else {
58
- // Create a WordPress exporter and let it handle the load
59
- $this->wp = new WordPress_Module();
60
- $this->wp->start();
61
- }
62
-
63
- add_action( 'redirection_log_delete', array( $this, 'expire_logs' ) );
64
-
65
- $this->monitor = new Red_Monitor( $this->get_options() );
66
- add_action( 'template_redirect', array( &$this, 'template_redirect' ) );
67
- }
68
-
69
- public function init() {
70
- load_plugin_textdomain( 'redirection', false, dirname( plugin_basename( __FILE__ ) ).'/locale/' );
71
- }
72
-
73
- private function render( $template, $template_vars = array() ) {
74
- foreach ( $template_vars AS $key => $val ) {
75
- $$key = $val;
76
- }
77
-
78
- if ( file_exists( dirname( __FILE__ )."/view/admin/$template.php" ) )
79
- include dirname( __FILE__ )."/view/admin/$template.php";
80
- }
81
-
82
- private function capture( $ug_name, $ug_vars = array() ) {
83
- ob_start();
84
-
85
- $this->render( $ug_name, $ug_vars );
86
- $output = ob_get_contents();
87
-
88
- ob_end_clean();
89
- return $output;
90
- }
91
-
92
- private function render_error( $message ) {
93
- ?>
94
- <div class="fade error" id="message">
95
- <p><?php echo $message ?></p>
96
- </div>
97
- <?php
98
- }
99
-
100
- private function render_message( $message, $timeout = 0 ) {
101
- ?>
102
- <div class="updated" id="message" onclick="this.parentNode.removeChild(this)">
103
- <p><?php echo $message ?></p>
104
- </div>
105
- <?php
106
- }
107
-
108
- function update() {
109
- $version = get_option( 'redirection_version' );
110
-
111
- if ( $version != REDIRECTION_VERSION ) {
112
- include_once dirname( __FILE__ ).'/models/database.php';
113
-
114
- $database = new RE_Database();
115
- return $database->upgrade( $version, REDIRECTION_VERSION );
116
- }
117
-
118
- return true;
119
- }
120
-
121
- private function select( $items, $default = '' ) {
122
- foreach ( $items AS $key => $value ) {
123
- if ( is_array( $value ) ) {
124
- echo '<optgroup label="'.esc_attr( $key ).'">';
125
-
126
- foreach ( $value AS $sub => $subvalue ) {
127
- echo '<option value="'.esc_attr( $sub ).'"'.( $sub == $default ? ' selected="selected"' : '' ).'>'.esc_html( $subvalue ).'</option>';
128
- }
129
-
130
- echo '</optgroup>';
131
- }
132
- else
133
- echo '<option value="'.esc_attr( $key ).'"'.( $key == $default ? ' selected="selected"' : '' ).'>'.esc_html( $value ).'</option>';
134
- }
135
- }
136
-
137
- function set_per_page( $status, $option, $value ) {
138
- if ( $option == 'redirection_log_per_page' )
139
- return $value;
140
- return $status;
141
- }
142
-
143
- function plugin_settings( $links ) {
144
- $settings_link = '<a href="tools.php?page='.basename( __FILE__ ).'&amp;sub=options">'.__( 'Settings', 'redirection' ).'</a>';
145
- array_unshift( $links, $settings_link );
146
- return $links;
147
- }
148
-
149
- function redirection_head() {
150
- $version = get_plugin_data( __FILE__ );
151
- $version = $version['Version'];
152
-
153
- include dirname( __FILE__ ).'/models/pager.php';
154
-
155
- $this->inject();
156
-
157
- if ( !isset( $_GET['sub'] ) || ( isset( $_GET['sub'] ) && ( in_array( $_GET['sub'], array( 'log', '404s', 'groups' ) ) ) ) )
158
- add_screen_option( 'per_page', array( 'label' => __( 'Log entries', 'redirection' ), 'default' => 25, 'option' => 'redirection_log_per_page' ) );
159
-
160
- wp_enqueue_script( 'redirection', plugin_dir_url( __FILE__ ).'redirection.js', array( 'jquery-form', 'jquery-ui-sortable' ), $version );
161
- wp_enqueue_style( 'redirection', plugin_dir_url( __FILE__ ).'admin.css', $version );
162
-
163
- wp_localize_script( 'redirection', 'Redirectioni10n', array(
164
- 'error_msg' => __( 'Sorry, unable to do that. Please try refreshing the page.' ),
165
- ) );
166
- }
167
-
168
- function admin_menu() {
169
- add_management_page( __( "Redirection", 'redirection' ), __( "Redirection", 'redirection' ), apply_filters( 'redirection_role', 'administrator' ), basename( __FILE__ ), array( &$this, "admin_screen" ) );
170
- }
171
-
172
- function expire_logs() {
173
- global $wpdb;
174
-
175
- $options = $this->get_options();
176
- $cleanup = false;
177
-
178
- if ( $options['expire_redirect'] > 0 ) {
179
- $cleanup = true;
180
- $logs = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}redirection_logs WHERE created < DATE_SUB(NOW(), INTERVAL %d DAY)", $options['expire_redirect'] ) );
181
- if ( $logs > 0 )
182
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}redirection_logs WHERE created < DATE_SUB(NOW(), INTERVAL %d DAY) LIMIT 1000", $options['expire_redirect'] ) );
183
- }
184
-
185
- if ( $options['expire_404'] > 0 ) {
186
- $cleanup = true;
187
- $l404 = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}redirection_404 WHERE created < DATE_SUB(NOW(), INTERVAL %d DAY)", $options['expire_404'] ) );
188
-
189
- if ( $l404 > 0 )
190
- $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}redirection_404 WHERE created < DATE_SUB(NOW(), INTERVAL %d DAY) LIMIT 1000", $options['expire_404'] ) );
191
- }
192
-
193
- if ( $cleanup ) {
194
- $rand = mt_rand( 1, 5000 );
195
-
196
- if ( $rand == 11 )
197
- $wpdb->query( "OPTIMIZE TABLE {$wpdb->prefix}redirection_logs" );
198
- elseif ( $rand == 12 )
199
- $wpdb->query( "OPTIMIZE TABLE {$wpdb->prefix}redirection_404" );
200
- }
201
- }
202
-
203
- function admin_screen() {
204
- $this->update();
205
-
206
- $options = $this->get_options();
207
- if ( ( $options['expire_404'] > 0 || $options['expire_redirect'] > 0 ) && !wp_next_scheduled( 'redirection_log_delete' ) )
208
- wp_schedule_event( time(), 'daily', 'redirection_log_delete' );
209
-
210
- if ( isset($_GET['sub']) ) {
211
- if ( $_GET['sub'] == 'log' )
212
- return $this->admin_screen_log();
213
- elseif ( $_GET['sub'] == '404s' )
214
- return $this->admin_screen_404();
215
- elseif ( $_GET['sub'] == 'options' )
216
- return $this->admin_screen_options();
217
- elseif ( $_GET['sub'] == 'process' )
218
- return $this->admin_screen_process();
219
- elseif ( $_GET['sub'] == 'groups' )
220
- return $this->admin_groups( isset( $_GET['id'] ) ? intval( $_GET['id'] ) : 0 );
221
- elseif ( $_GET['sub'] == 'modules' )
222
- return $this->admin_screen_modules();
223
- elseif ( $_GET['sub'] == 'support' )
224
- return $this->render('support', array( 'options' => $this->get_options() ) );
225
- }
226
-
227
- return $this->admin_redirects( isset( $_GET['id'] ) ? intval( $_GET['id'] ) : 0 );
228
- }
229
-
230
- function admin_screen_modules() {
231
- $options = $this->get_options();
232
- $pager = new Redirection_Module_Table( $options['token'] );
233
- $pager->prepare_items();
234
-
235
- $this->render( 'module_list', array( 'options' => $options, 'table' => $pager ) );
236
- }
237
-
238
- function get_options() {
239
- $options = get_option( 'redirection_options' );
240
- if ( $options === false )
241
- $options = array();
242
-
243
- $defaults = array(
244
- 'support' => false,
245
- 'token' => '',
246
- 'monitor_post' => 0,
247
- 'auto_target' => '',
248
- 'expire_redirect' => 7,
249
- 'expire_404' => 7,
250
- );
251
-
252
- foreach ( $defaults AS $key => $value ) {
253
- if ( !isset( $options[$key] ) )
254
- $options[$key] = $value;
255
- }
256
-
257
- if ( isset( $options['expire'] ) ) {
258
- if ( isset( $options['log_redirection'] ) )
259
- $options['expire_redirect'] = $options['expire'];
260
-
261
- if ( isset( $options['log_404s'] ) )
262
- $options['expire_404'] = $options['expire'];
263
-
264
- unset( $options['expire'] );
265
- unset( $options['log_redirection'] );
266
- unset( $options['log_404s'] );
267
-
268
- update_option( 'redirection_options', $options );
269
- }
270
-
271
- $options['lookup'] = 'http://urbangiraffe.com/map/?ip=';
272
-
273
- return $options;
274
- }
275
-
276
- function inject() {
277
- $options = $this->get_options();
278
-
279
- if ( isset( $_POST['id'] ) && !isset( $_POST['action'] ) ) {
280
- wp_safe_redirect( add_query_arg( 'id', intval( $_POST['id'] ), $_SERVER['REQUEST_URI'] ) );
281
- die();
282
- }
283
-
284
- if ( isset( $_GET['token'] ) && isset( $_GET['page'] ) && isset( $_GET['sub'] ) && $_GET['token'] == $options['token'] && $_GET['page'] == 'redirection.php' ) {
285
- include dirname( __FILE__ ).'/models/file_io.php';
286
-
287
- $exporter = Red_FileIO::create( $_GET['sub'] );
288
- if ( $exporter ) {
289
- $items = Red_Item::get_all_for_module( intval( $_GET['module'] ) );
290
-
291
- $exporter->export( $items );
292
- die();
293
- }
294
- }
295
- elseif ( isset( $_POST['export-csv'] ) && check_admin_referer( 'redirection-log_management' ) ) {
296
- if ( isset( $_GET['sub'] ) && $_GET['sub'] == 'log' )
297
- RE_Log::export_to_csv();
298
- else
299
- RE_404::export_to_csv();
300
- die();
301
- }
302
- }
303
-
304
- function admin_screen_options() {
305
- if ( isset( $_POST['regenerate'] ) && check_admin_referer( 'redirection-update_options' ) ) {
306
- $options = $this->get_options();
307
- $options['token'] = md5( uniqid() );
308
-
309
- update_option( 'redirection_options', $options );
310
-
311
- $this->render_message( __( 'Your options were updated', 'redirection' ) );
312
- }
313
- elseif ( isset( $_POST['update'] ) && check_admin_referer( 'redirection-update_options' ) ) {
314
- $options['monitor_post'] = stripslashes( $_POST['monitor_post'] );
315
- $options['auto_target'] = stripslashes( $_POST['auto_target'] );
316
- $options['support'] = isset( $_POST['support'] ) ? true : false;
317
- $options['token'] = stripslashes( $_POST['token'] );
318
- $options['expire_redirect'] = min( intval( $_POST['expire_redirect'] ), 60 );
319
- $options['expire_404'] = min( intval( $_POST['expire_404'] ), 60 );
320
-
321
- if ( trim( $options['token'] ) == '' )
322
- $options['token'] = md5( uniqid() );
323
-
324
- update_option( 'redirection_options', $options );
325
-
326
- $this->render_message( __( 'Your options were updated', 'redirection' ) );
327
- }
328
- elseif ( isset( $_POST['delete'] ) && check_admin_referer( 'redirection-delete_plugin' ) ) {
329
- include dirname( __FILE__ ).'/models/database.php';
330
-
331
- $db = new RE_Database();
332
- $db->remove( __FILE__ );
333
-
334
- $this->render_message( __( 'Redirection data has been deleted and the plugin disabled', 'redirection' ) );
335
- return;
336
- }
337
- elseif ( isset( $_POST['import'] ) && check_admin_referer( 'redirection-import' ) ) {
338
- include dirname( __FILE__ ).'/models/file_io.php';
339
-
340
- $count = Red_FileIO::import( $_POST['group'], $_FILES['upload'] );
341
-
342
- if ( $count > 0 )
343
- $this->render_message( sprintf( _n( '%d redirection was successfully imported','%d redirections were successfully imported', $count, 'redirection' ), $count ) );
344
- else
345
- $this->render_message( __( 'No items were imported', 'redirection' ) );
346
- }
347
-
348
- $groups = Red_Group::get_for_select();
349
- $this->render( 'options', array( 'options' => $this->get_options(), 'groups' => $groups ) );
350
- }
351
-
352
- function admin_screen_log() {
353
- $options = $this->get_options();
354
-
355
- if ( isset( $_POST['delete-all'] ) && check_admin_referer( 'redirection-log_management' ) ) {
356
- RE_Log::delete_all();
357
- $this->render_message( __( 'Your logs have been deleted', 'redirection' ) );
358
- }
359
-
360
- $table = new Redirection_Log_Table( $options );
361
-
362
- if ( isset( $_GET['module'] ) )
363
- $table->prepare_items( 'module', intval( $_GET['module'] ) );
364
- else if (isset($_GET['group']))
365
- $table->prepare_items( 'group', intval( $_GET['group'] ) );
366
- else if (isset($_GET['redirect']))
367
- $table->prepare_items( 'redirect', intval( $_GET['redirect'] ) );
368
- else
369
- $table->prepare_items();
370
-
371
- $this->render( 'log', array( 'options' => $options, 'table' => $table, 'lookup' => $options['lookup'], 'type' => 'log' ) );
372
- }
373
-
374
- function admin_screen_404() {
375
- if ( isset( $_POST['delete-all'] ) && check_admin_referer( 'redirection-log_management' ) ) {
376
- RE_404::delete_all();
377
- $this->render_message( __( 'Your logs have been deleted', 'redirection' ) );
378
- }
379
-
380
- $options = $this->get_options();
381
-
382
- $table = new Redirection_404_Table( $options );
383
- $table->prepare_items( isset( $_GET['ip'] ) ? $_GET['ip'] : false );
384
-
385
- $this->render( 'log', array( 'options' => $options, 'table' => $table, 'lookup' => $options['lookup'], 'type' => '404s' ) );
386
- }
387
-
388
- function admin_groups( $module ) {
389
- if ( isset( $_POST['add'] ) && check_admin_referer( 'redirection-add_group' ) ) {
390
- if ( Red_Group::create( stripslashes_deep( $_POST ) ) ) {
391
- $this->render_message( __( 'Your group was added successfully', 'redirection' ) );
392
- Red_Module::flush( $module );
393
- }
394
- else
395
- $this->render_error( __( 'Please specify a group name', 'redirection' ) );
396
- }
397
-
398
- if ( $module == 0 )
399
- $module = Red_Module::get_first_id();
400
-
401
- $table = new Redirection_Group_Table( Red_Module::get_for_select(), $module );
402
- $table->prepare_items();
403
-
404
- $module = Red_Module::get( $module );
405
- if ( $module )
406
- $this->render( 'group_list', array( 'options' => $this->get_options(), 'table' => $table, 'modules' => Red_Module::get_for_select(), 'module' => $module ) );
407
- else
408
- $this->render_message( __( 'Unknown module', 'redirection' ) );
409
- }
410
-
411
- function admin_redirects( $group_id ) {
412
- if ( $group_id == 0 )
413
- $group_id = Red_Group::get_first_id();
414
-
415
- $group = Red_Group::get( $group_id );
416
- if ( $group === false ) {
417
- $group = Red_Group::create( array( 'name' => 'Redirections', 'module_id' => 1 ) );
418
- }
419
-
420
- $table = new Redirection_Table( Red_Group::get_for_select(), $group );
421
- $table->prepare_items();
422
-
423
- $this->render( 'item_list', array( 'options' => $this->get_options(), 'group' => $group, 'table' => $table, 'date_format' => get_option( 'date_format' ) ) );
424
- }
425
-
426
- function setMatched( $match ) {
427
- $this->hasMatched = $match;
428
- }
429
-
430
- function hasMatched() {
431
- return $this->hasMatched;
432
- }
433
-
434
- function locales() {
435
- $locales = array();
436
- if ( file_exists( dirname( __FILE__ ).'/readme.txt' ) ) {
437
- $readme = file_get_contents( dirname( __FILE__ ).'/readme.txt' );
438
-
439
- $start = strpos( $readme, 'Redirection is available in' );
440
- $end = strpos( $readme, '==', $start );
441
- if ( $start !== false && $end !== false ) {
442
- if ( preg_match_all( '/^\* (.*?) by (.*?)/m', substr( $readme, $start, $end ), $matches ) > 0 ) {
443
- $locales = $matches[1];
444
- }
445
- }
446
-
447
- sort( $locales );
448
- }
449
-
450
- return $locales;
451
- }
452
-
453
- /**
454
- * Matches 404s
455
- */
456
- function template_redirect() {
457
- if ( is_404() ) {
458
- $options = $this->get_options();
459
-
460
- if ( isset( $options['expire_404'] ) && $options['expire_404'] >= 0 ) {
461
- RE_404::create( red_get_url(), red_user_agent(), red_ip(), red_http_referrer() );
462
- }
463
- }
464
- }
465
-
466
- public function ajax_log_delete() {
467
- if ( check_ajax_referer( 'redirection-items' ) ) {
468
- if ( preg_match_all( '/=(\d*)/', $_POST['checked'], $items ) > 0) {
469
- foreach ( $items[1] AS $item ) {
470
- RE_Log::delete( intval( $item ) );
471
- }
472
- }
473
- }
474
- }
475
-
476
- private function check_ajax_referer( $nonce ) {
477
- if ( check_ajax_referer( $nonce, false, false ) === false )
478
- $this->output_ajax_response( array( 'error' => __( 'Unable to perform action' ).' - bad nonce' ) );
479
- }
480
-
481
- public function ajax_module_edit() {
482
- $module_id = intval( $_POST['id'] );
483
-
484
- $this->check_ajax_referer( 'red_edit-'.$module_id );
485
-
486
- $module = Red_Module::get( $module_id );
487
- if ( $module )
488
- $json['html'] = $this->capture( 'module_edit', array( 'module' => $module ) );
489
- else
490
- $json['error'] = __( 'Unable to perform action' ).' - could not find module';
491
-
492
- $this->output_ajax_response( $json );
493
- }
494
-
495
- public function ajax_module_save() {
496
- global $hook_suffix;
497
-
498
- include dirname( __FILE__ ).'/models/pager.php';
499
-
500
- $hook_suffix = '';
501
- $module_id = intval( $_POST['id'] );
502
- $options = $this->get_options();
503
-
504
- $this->check_ajax_referer( 'red_module_save_'.$module_id );
505
-
506
- $module = Red_Module::get( $module_id );
507
-
508
- if ( $module ) {
509
- $module->update( $_POST );
510
-
511
- $pager = new Redirection_Module_Table( $options['token'] );
512
- $json = array( 'html' => $pager->column_name( $module ) );
513
- }
514
- else
515
- $json['error'] = __( 'Unable to perform action' ).' - could not find module';
516
-
517
- $this->output_ajax_response( $json );
518
- }
519
-
520
- public function ajax_group_edit() {
521
- $group_id = intval( $_POST['id'] );
522
-
523
- $this->check_ajax_referer( 'red-edit_'.$group_id );
524
-
525
- $group = Red_Group::get( $group_id );
526
- if ( $group )
527
- $json['html'] = $this->capture( 'group_edit', array( 'group' => $group, 'modules' => Red_Module::get_for_select() ) );
528
- else
529
- $json['error'] = __( 'Unable to perform action' ).' - could not find group';
530
-
531
- $this->output_ajax_response( $json );
532
- }
533
-
534
- public function ajax_group_save() {
535
- global $hook_suffix;
536
-
537
- include dirname( __FILE__ ).'/models/pager.php';
538
-
539
- $hook_suffix = '';
540
- $group_id = intval( $_POST['id'] );
541
-
542
- $this->check_ajax_referer( 'redirection-group_save_'.$group_id );
543
-
544
- $group = Red_Group::get( $group_id );
545
- if ( $group ) {
546
- $group->update( $_POST );
547
-
548
- $pager = new Redirection_Group_Table( array(), false );
549
- $json = array( 'html' => $pager->column_name( $group ) );
550
- }
551
- else
552
- $json['error'] = __( 'Unable to perform action' ).' - could not find redirect';
553
-
554
- $this->output_ajax_response( $json );
555
- }
556
-
557
- public function ajax_redirect_edit() {
558
- $this->check_ajax_referer( 'red-edit_'.intval( $_POST['id'] ) );
559
- $redirect = Red_Item::get_by_id( intval( $_POST['id'] ) );
560
-
561
- if ( $redirect )
562
- $json['html'] = $this->capture( 'item_edit', array( 'redirect' => $redirect, 'groups' => Red_Group::get_for_select() ) );
563
- else
564
- $json['error'] = __( 'Unable to perform action' ).' - could not find redirect';
565
-
566
- $this->output_ajax_response( $json );
567
- }
568
-
569
- public function ajax_redirect_save() {
570
- global $hook_suffix;
571
-
572
- include dirname( __FILE__ ).'/models/pager.php';
573
-
574
- $hook_suffix = '';
575
-
576
- $red_id = intval( $_POST['id'] );
577
-
578
- $this->check_ajax_referer( 'redirection-redirect_save_'.$red_id );
579
-
580
- $redirect = Red_Item::get_by_id( $red_id );
581
- if ( $redirect ) {
582
- $redirect->update( $_POST );
583
-
584
- $pager = new Redirection_Table( array() );
585
- $json = array( 'html' => $pager->column_url( $redirect ), 'code' => $redirect->get_action_code() );
586
- }
587
- else
588
- $json['error'] = __( 'Unable to perform action' ).' - could not find redirect';
589
-
590
- $this->output_ajax_response( $json );
591
- }
592
-
593
- public function ajax_redirect_add() {
594
- global $hook_suffix;
595
-
596
- include dirname( __FILE__ ).'/models/pager.php';
597
-
598
- $hook_suffix = '';
599
-
600
- $this->check_ajax_referer( 'redirection-redirect_add' );
601
 
602
- $item = Red_Item::create( $_POST );
603
- if ( is_wp_error( $item ) )
604
- $json['error'] = $item->get_error_message();
605
- elseif ( $item !== false ) {
606
- $pager = new Redirection_Table( array() );
607
- $json = array( 'html' => $pager->get_row( $item ) );
608
- }
609
- else
610
- $json['error'] = __( 'Sorry, but your redirection was not created', 'redirection' );
611
 
612
- $this->output_ajax_response( $json );
613
- }
 
 
 
 
 
 
614
 
615
- private function output_ajax_response( array $data ) {
616
- header( 'Content-Type: application/json' );
617
- echo json_encode( $data );
618
- die();
619
  }
620
- }
621
-
622
- function red_get_url() {
623
- if ( isset( $_SERVER['REQUEST_URI'] ) )
624
- return $_SERVER['REQUEST_URI'];
625
- return '';
626
- }
627
-
628
- function red_user_agent() {
629
- if ( isset( $_SERVER['HTTP_USER_AGENT'] ) )
630
- return $_SERVER['HTTP_USER_AGENT'];
631
- return false;
632
- }
633
-
634
- function red_http_referrer() {
635
- if ( isset( $_SERVER['HTTP_REFERER'] ) )
636
- return $_SERVER['HTTP_REFERER'];
637
- return false;
638
- }
639
 
640
- function red_ip() {
641
- if ( isset( $_SERVER['REMOTE_ADDR'] ) )
642
- return $_SERVER['REMOTE_ADDR'];
643
- elseif ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
644
- return $_SERVER['HTTP_X_FORWARDED_FOR'];
645
- return '';
646
  }
647
 
648
- // Instantiate the plugin
649
- $redirection = new Redirection;
 
 
3
  Plugin Name: Redirection
4
  Plugin URI: http://urbangiraffe.com/plugins/redirection/
5
  Description: Manage all your 301 redirects and monitor 404 errors
6
+ Version: 2.3.13
7
  Author: John Godley
8
  Author URI: http://urbangiraffe.com
9
  ============================================================================================================
19
  ============================================================================================================
20
  */
21
 
 
 
 
 
 
 
 
 
 
22
  define( 'REDIRECTION_VERSION', '2.3.1' ); // DB schema version. Only change if DB needs changing
23
+ define( 'REDIRECTION_FILE', __FILE__ );
24
 
25
+ include dirname( __FILE__ ).'/models/module.php';
26
+ include dirname( __FILE__ ).'/models/log.php';
27
+ include dirname( __FILE__ ).'/models/flusher.php';
28
+ include dirname( __FILE__ ).'/models/match.php';
29
+ include dirname( __FILE__ ).'/models/action.php';
30
+ include dirname( __FILE__ ).'/models/redirect.php';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
+ function red_get_options() {
33
+ $options = get_option( 'redirection_options' );
34
+ if ( $options === false )
35
+ $options = array();
 
 
 
 
 
36
 
37
+ $defaults = array(
38
+ 'support' => false,
39
+ 'token' => '',
40
+ 'monitor_post' => 0,
41
+ 'auto_target' => '',
42
+ 'expire_redirect' => 7,
43
+ 'expire_404' => 7,
44
+ );
45
 
46
+ foreach ( $defaults AS $key => $value ) {
47
+ if ( !isset( $options[$key] ) )
48
+ $options[$key] = $value;
 
49
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
50
 
51
+ $options['lookup'] = apply_filters( 'red_lookup_ip', 'http://urbangiraffe.com/map/?ip=' );
52
+ return $options;
 
 
 
 
53
  }
54
 
55
+ if ( is_admin() )
56
+ include dirname( __FILE__ ).'/redirection-admin.php';
57
+ else
58
+ include dirname( __FILE__ ).'/redirection-front.php';
view/admin/submenu.php CHANGED
@@ -2,12 +2,12 @@
2
 
3
  <ul class="subsubsub">
4
  <li>
5
- <a <?php if ( !isset( $_GET['sub'] ) || $_GET['sub'] == '' ) echo 'class="current"'; ?> href="<?php echo admin_url( 'tools.php?page=redirection.php' ); ?><?php if ( isset( $_GET['id'] ) ) echo '&amp;id='.intval( $_GET['id'] ) ?>">
6
  <?php _e( 'Redirects', 'redirection' ); ?>
7
  </a> |
8
  </li>
9
  <li>
10
- <a <?php if ( isset( $_GET['sub'] ) && $_GET['sub'] == 'groups' ) echo 'class="current"'; ?> href="<?php echo admin_url( 'tools.php?page=redirection.php' ); ?>&amp;sub=groups<?php if ( isset( $_GET['id'] ) ) echo '&amp;id='.intval( $_GET['id'] ) ?>">
11
  <?php _e( 'Groups', 'redirection' ); ?>
12
  </a> |
13
  </li>
2
 
3
  <ul class="subsubsub">
4
  <li>
5
+ <a <?php if ( !isset( $_GET['sub'] ) || $_GET['sub'] == '' ) echo 'class="current"'; ?> href="<?php echo admin_url( 'tools.php?page=redirection.php' ); ?>">
6
  <?php _e( 'Redirects', 'redirection' ); ?>
7
  </a> |
8
  </li>
9
  <li>
10
+ <a <?php if ( isset( $_GET['sub'] ) && $_GET['sub'] == 'groups' ) echo 'class="current"'; ?> href="<?php echo admin_url( 'tools.php?page=redirection.php' ); ?>&amp;sub=groups">
11
  <?php _e( 'Groups', 'redirection' ); ?>
12
  </a> |
13
  </li>
view/admin/support.php CHANGED
@@ -5,7 +5,7 @@
5
  <h2><?php _e ('Redirection Support', 'redirection'); ?></h2>
6
  <?php $this->render( 'submenu', array( 'options' => $options ) ); ?>
7
 
8
- <p style="clear: both">
9
  <?php _e( 'Redirection is free to use - life is wonderful and lovely! However, it has required a great deal of time and effort to develop and if it has been useful you can help support this development by <strong>making a small donation</strong>.', 'redirection'); ?>
10
  <?php _e( 'This will act as an incentive for me to carry on developing. You get some useful software and I get to carry on making it. Everybody wins.', 'redirection'); ?>
11
  </p>
@@ -32,7 +32,7 @@
32
  <input type="hidden" name="tax" value="0">
33
  <input type="hidden" name="lc" value="US">
34
  <input type="hidden" name="bn" value="PP-DonationsBF">
35
- <input type="image" style="border: none" src="<?php echo $this->url () ?>/images/donate.gif" border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!"/>
36
  </form>
37
 
38
  <p><strong>$16</strong><br/><?php _e( 'Individual<br/>Donation', 'redirection' ); ?></p>
@@ -53,7 +53,7 @@
53
  <input type="hidden" name="tax" value="0">
54
  <input type="hidden" name="lc" value="US">
55
  <input type="hidden" name="bn" value="PP-DonationsBF">
56
- <input type="image" style="border: none" src="<?php echo $this->url () ?>/images/donate.gif" border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!"/>
57
  </form>
58
  <p><strong>$$$</strong><br/><?php _e( 'Commercial<br/>Donation', 'redirection' ); ?></p>
59
  </li>
@@ -69,6 +69,5 @@
69
  <?php endforeach; ?>
70
  </ul>
71
 
72
- <p style="clear: both"><br/><?php _e( 'All translators will have a link to their website placed on the plugin homepage at <a href="http://urbangiraffe.com/plugins/redirection/">UrbanGiraffe</a>, in addition to being an individual supporter.', 'redirection' )?></p>
73
  <p><?php _e( 'Full details of producing a translation can be found in this <a href="http://urbangiraffe.com/articles/translating-wordpress-themes-and-plugins/">guide to translating WordPress plugins</a>.', 'redirection' )?>
74
  </div>
5
  <h2><?php _e ('Redirection Support', 'redirection'); ?></h2>
6
  <?php $this->render( 'submenu', array( 'options' => $options ) ); ?>
7
 
8
+ <p style="clear: both; padding-top: 20px">
9
  <?php _e( 'Redirection is free to use - life is wonderful and lovely! However, it has required a great deal of time and effort to develop and if it has been useful you can help support this development by <strong>making a small donation</strong>.', 'redirection'); ?>
10
  <?php _e( 'This will act as an incentive for me to carry on developing. You get some useful software and I get to carry on making it. Everybody wins.', 'redirection'); ?>
11
  </p>
32
  <input type="hidden" name="tax" value="0">
33
  <input type="hidden" name="lc" value="US">
34
  <input type="hidden" name="bn" value="PP-DonationsBF">
35
+ <input type="image" style="border: none" src="<?php echo plugins_url( '/images/donate.gif', REDIRECTION_FILE ); ?>" border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!"/>
36
  </form>
37
 
38
  <p><strong>$16</strong><br/><?php _e( 'Individual<br/>Donation', 'redirection' ); ?></p>
53
  <input type="hidden" name="tax" value="0">
54
  <input type="hidden" name="lc" value="US">
55
  <input type="hidden" name="bn" value="PP-DonationsBF">
56
+ <input type="image" style="border: none" src="<?php echo plugins_url( '/images/donate.gif', REDIRECTION_FILE ); ?>" border="0" name="submit" alt="Make payments with PayPal - it's fast, free and secure!"/>
57
  </form>
58
  <p><strong>$$$</strong><br/><?php _e( 'Commercial<br/>Donation', 'redirection' ); ?></p>
59
  </li>
69
  <?php endforeach; ?>
70
  </ul>
71
 
 
72
  <p><?php _e( 'Full details of producing a translation can be found in this <a href="http://urbangiraffe.com/articles/translating-wordpress-themes-and-plugins/">guide to translating WordPress plugins</a>.', 'redirection' )?>
73
  </div>