PluginProbe
Redirection / 2.4.4
Redirection v2.4.4
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 / models / redirect.php

redirect.php in Redirection 2.4.4, at models/redirect.php

456 lines 13.8 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 class Red_Item {
4 private $id = null;
5 private $created;
6 private $referrer;
7 private $url = null;
8 private $regex = false;
9 private $action_data = null;
10 private $action_code = 0;
11 private $action_type;
12 private $match_type;
13 private $title;
14 private $last_access = null;
15 private $last_count = 0;
16 private $tracking = true;
17 private $status;
18 private $position;
19 private $group_id;
20
21 function __construct( $values, $type = '', $match = '' ) {
22 if ( is_object( $values ) ) {
23 foreach ( $values as $key => $value ) {
24 $this->$key = $value;
25 }
26
27 if ( $this->match_type === '' ) {
28 $this->match_type = 'url';
29 }
30
31 $this->match = Red_Match::create( $this->match_type, $this->action_data );
32 $this->match->id = $this->id;
33 $this->match->action_code = $this->action_code;
34
35 $action = false;
36
37 if ( $this->action_type ) {
38 $action = Red_Action::create( $this->action_type, $this->action_code );
39 }
40
41 if ( $action ) {
42 $this->action = $action;
43 $this->match->action = $this->action;
44 }
45 else
46 $this->action = Red_Action::create( 'nothing', 0 );
47
48 if ( $this->last_access == '0000-00-00 00:00:00' )
49 $this->last_access = 0;
50 else
51 $this->last_access = mysql2date( 'U', $this->last_access );
52 }
53 else {
54 $this->url = $values;
55 $this->type = $type;
56 $this->match = $match;
57 }
58 }
59
60 static function get_all_for_module( $module ) {
61 global $wpdb;
62
63 $sql = $wpdb->prepare( "SELECT @redirection_items.*,@redirection_groups.tracking FROM @redirection_items INNER JOIN @redirection_groups ON @redirection_groups.id=@redirection_items.group_id AND @redirection_groups.status='enabled' AND @redirection_groups.module_id=%d WHERE @redirection_items.status='enabled' ORDER BY @redirection_groups.position,@redirection_items.position", $module );
64 $sql = str_replace( '@', $wpdb->prefix, $sql );
65
66 $rows = $wpdb->get_results( $sql );
67 $items = array();
68 if ( count( $rows) > 0 ) {
69 foreach ( $rows AS $row ) {
70 $items[] = new Red_Item( $row );
71 }
72 }
73
74 return $items;
75 }
76
77 static function get_for_url( $url, $type ) {
78 global $wpdb;
79
80 $sql = $wpdb->prepare( "SELECT @redirection_items.*,@redirection_groups.position AS group_pos FROM @redirection_items INNER JOIN @redirection_groups ON @redirection_groups.id=@redirection_items.group_id AND @redirection_groups.status='enabled' AND @redirection_groups.module_id=%d WHERE (@redirection_items.regex=1 OR @redirection_items.url=%s)", WordPress_Module::MODULE_ID, $url );
81 $sql = str_replace( '@', $wpdb->prefix, $sql);
82
83 $rows = $wpdb->get_results( $sql ) ;
84 $items = array();
85 if ( count( $rows ) > 0 ) {
86 foreach ( $rows AS $row ) {
87 $items[] = array( 'position' => ( $row->group_pos * 1000 ) + $row->position, 'item' => new Red_Item( $row ) );
88 }
89 }
90
91 usort( $items, array( 'Red_Item', 'sort_urls' ) );
92 $items = array_map( array( 'Red_Item', 'reduce_sorted_items' ), $items );
93
94 // Sort it in PHP
95 ksort( $items );
96 $items = array_values( $items );
97 return $items;
98 }
99
100 static function sort_urls( $first, $second ) {
101 if ( $first['position'] === $second['position'] )
102 return 0;
103
104 return $first['position'] < $second['position'];
105 }
106
107 static function reduce_sorted_items( $item ) {
108 return $item['item'];
109 }
110
111 static function get_by_module( $module ) {
112 global $wpdb;
113
114 $sql = "SELECT {$wpdb->prefix}redirection_items.* FROM {$wpdb->prefix}redirection_items INNER JOIN {$wpdb->prefix}redirection_groups ON {$wpdb->prefix}redirection_groups.id={$wpdb->prefix}redirection_items.group_id";
115 $sql .= $wpdb->prepare( " WHERE {$wpdb->prefix}redirection_groups.module_id=%d", $module );
116
117 $rows = $wpdb->get_results( $sql );
118 $items = array();
119
120 foreach( (array)$rows AS $row ) {
121 $items[] = new Red_Item( $row );
122 }
123
124 return $items;
125 }
126
127 static function get_by_id( $id ) {
128 global $wpdb;
129
130 $row = $wpdb->get_row( $wpdb->prepare( "SELECT * FROM {$wpdb->prefix}redirection_items WHERE id=%d", $id ) );
131 if ( $row )
132 return new Red_Item( $row );
133 return false;
134 }
135
136 static function auto_generate() {
137 $options = red_get_options();
138 $id = time();
139
140 $url = $options['auto_target'];
141 $url = str_replace( '$dec$', $id, $url );
142 $url = str_replace( '$hex$', sprintf( '%x', $id), $url );
143 return $url;
144 }
145
146 static function create( array $details ) {
147 global $wpdb;
148
149 $details = array_map( 'trim', $details );
150 $details = array_map( 'stripslashes', $details );
151
152 // Auto generate URLs
153 if ( empty( $details['source'] ) )
154 $details['source'] = self::auto_generate();
155
156 if ( empty( $details['target'] ) )
157 $details['target'] = self::auto_generate();
158
159 // Make sure we don't redirect to ourself
160 if ( $details['source'] == $details['target'] )
161 return new WP_Error( 'redirect-add', __( 'Source and target URL must be different', 'redirection' ) );
162
163 $parsed_url = parse_url( $details['source'] );
164 $parsed_domain = parse_url( site_url() );
165
166 if ( isset( $parsed_url['scheme'] ) && ( $parsed_url['scheme'] === 'http' || $parsed_url['scheme'] === 'https' ) && $parsed_url['host'] !== $parsed_domain['host'] ) {
167 return new WP_Error( 'redirect-add', sprintf( __( 'You can only redirect from a relative URL (<code>%s</code>) on this domain (<code>%s</code>).', 'redirection' ), $parsed_url['path'], $parsed_domain['host'] ) );
168 }
169
170 $matcher = Red_Match::create( $details['match'] );
171 $group_id = intval( $details['group_id'] );
172 $group = Red_Group::get( $group_id );
173
174 if ( $group_id <= 0 || !$group )
175 return new WP_Error( 'redirect-add', __( 'Invalid group when creating redirect', 'redirection' ) );
176
177 if ( !$matcher )
178 return new WP_Error( 'redirect-add', __( 'Invalid source URL when creating redirect for given match type', 'redirection' ) );
179
180 $regex = ( isset( $details['regex']) && $details['regex'] != false) ? 1 : 0;
181 $position = $wpdb->get_var( $wpdb->prepare( "SELECT COUNT(*) FROM {$wpdb->prefix}redirection_items WHERE group_id=%d", $group_id ) );
182
183 $action = $details['red_action'];
184 $action_code = 0;
185 if ( $action == 'url' || $action == 'random' )
186 $action_code = 301;
187 elseif ( $action == 'error' )
188 $action_code = 404;
189
190 if ( isset( $details['action_code'] ) )
191 $action_code = intval( $details['action_code'] );
192
193 $data = array(
194 'url' => self::sanitize_url( $details['source'], $regex),
195 'action_type' => $details['red_action'],
196 'regex' => $regex,
197 'position' => $position,
198 'match_type' => $details['match'],
199 'action_data' => $matcher->data( $details ),
200 'action_code' => $action_code,
201 'last_access' => '0000-00-00 00:00:00',
202 'group_id' => $group_id
203 );
204
205 $data = apply_filters( 'redirection_create_redirect', $data );
206
207 $wpdb->delete( $wpdb->prefix.'redirection_items', array( 'url' => $data['action_data'], 'action_type' => $data['action_type'], 'action_data' => $data['url'] ) );
208
209 if ( $wpdb->insert( $wpdb->prefix.'redirection_items', $data ) ) {
210 Red_Module::flush( $group_id );
211 return self::get_by_id( $wpdb->insert_id );
212 }
213
214 return new WP_Error( 'redirect-add', __( 'Unable to add new redirect - delete Redirection from the options page and re-install' ) );
215 }
216
217 public function delete() {
218 global $wpdb;
219
220 $wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}redirection_items WHERE id=%d", $this->id ) );
221
222 RE_Log::delete_for_id( $this->id );
223
224 // Reorder all elements
225 $rows = $wpdb->get_results( "SELECT id FROM {$wpdb->prefix}redirection_items ORDER BY position" );
226 if ( count( $rows) > 0 ) {
227 foreach ( $rows AS $pos => $row ) {
228 $wpdb->update( $wpdb->prefix.'redirection_items', array( 'position' => $pos ), array( 'id' => $row->id ) );
229 }
230 }
231
232 Red_Module::flush( $this->group_id );
233 }
234
235 static function sanitize_url( $url, $regex ) {
236 // Make sure that the old URL is relative
237 $url = preg_replace( '@^https?://(.*?)/@', '/', $url );
238 $url = preg_replace( '@^https?://(.*?)$@', '/', $url );
239
240 if ( substr( $url, 0, 1) != '/' && $regex == false )
241 $url = '/'.$url;
242 return $url;
243 }
244
245 function update( $details ) {
246 if ( strlen( $details['old'] ) > 0 ) {
247 global $wpdb;
248
249 $details = array_map( 'stripslashes', $details );
250
251 $this->regex = isset( $details['regex'] ) ? 1 : 0;
252 $this->url = self::sanitize_url( $details['old'], $this->regex );
253 $this->title = $details['title'];
254
255 $data = $this->match->data( $details );
256
257 $this->action_code = 0;
258 if ( isset( $details['action_code'] ) )
259 $this->action_code = intval( $details['action_code'] );
260
261 $old_group = false;
262 if ( isset( $details['group_id'] ) ) {
263 $old_group = intval( $this->group_id );
264 $this->group_id = intval( $details['group_id'] );
265 }
266
267 // Save this
268 $wpdb->update( $wpdb->prefix.'redirection_items', array( 'url' => $this->url, 'regex' => $this->regex, 'action_code' => $this->action_code, 'action_data' => $data, 'group_id' => $this->group_id, 'title' => $this->title ), array( 'id' => $this->id ) );
269
270 if ( $old_group !== $this->group_id ) {
271 Red_Module::flush( $this->group_id );
272 Red_Module::flush( $old_group );
273 }
274 }
275 }
276
277 static function save_order( $items, $start ) {
278 global $wpdb;
279
280 foreach ( $items AS $pos => $id ) {
281 $wpdb->update( $wpdb->prefix.'redirection_items', array( 'position' => $pos + $start ), array( 'id' => $id ) );
282 }
283
284 Red_Module::flush( $this->group_id );
285 }
286
287 function matches( $url ) {
288 $this->url = str_replace( ' ', '%20', $this->url );
289 $matches = false;
290
291 // Check if we match the URL
292 if ( ( $this->regex == false && ( $this->url == $url || $this->url == rtrim( $url, '/' ) || $this->url == urldecode( $url ) ) ) ||( $this->regex == true && @preg_match( '@'.str_replace( '@', '\\@', $this->url).'@', $url, $matches) > 0) ||( $this->regex == true && @preg_match( '@'.str_replace( '@', '\\@', $this->url).'@', urldecode( $url ), $matches) > 0) ) {
293 // Check if our match wants this URL
294 $target = $this->match->get_target( $url, $this->url, $this->regex );
295
296 if ( $target ) {
297 $target = $this->replaceSpecialTags( $target );
298
299 $this->visit( $url, $target );
300
301 if ( $this->status === 'enabled' )
302 return $this->action->process_before( $this->action_code, $target );
303 }
304 }
305
306 return false;
307 }
308
309 function replaceSpecialTags( $target ) {
310 if ( is_numeric( $target ) )
311 $target = get_permalink( $target );
312 else {
313 $user = wp_get_current_user();
314 if ( !empty( $user ) ) {
315 $target = str_replace( '%userid%', $user->ID, $target );
316 $target = str_replace( '%userlogin%', isset( $user->user_login ) ? $user->user_login : '', $target );
317 $target = str_replace( '%userurl%', isset( $user->user_url ) ? $user->user_url : '', $target );
318 }
319 }
320
321 return $target;
322 }
323
324 function visit( $url, $target ) {
325 if ( $this->tracking && $this->id ) {
326 global $wpdb, $redirection;
327
328 // Update the counters
329 $count = $this->last_count + 1;
330 $wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}redirection_items SET last_count=%d, last_access=NOW() WHERE id=%d", $count, $this->id ) );
331
332 if ( isset( $_SERVER['HTTP_X_FORWARDED_FOR'] ) )
333 $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
334 elseif ( isset( $_SERVER['REMOTE_ADDR'] ) )
335 $ip = $_SERVER['REMOTE_ADDR'];
336
337 $options = red_get_options();
338 if ( isset( $options['expire_redirect'] ) && $options['expire_redirect'] >= 0 )
339 $log = RE_Log::create( $url, $target, $_SERVER['HTTP_USER_AGENT'], $ip, isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '', array( 'redirect_id' => $this->id, 'group_id' => $this->group_id) );
340 }
341 }
342
343 public function is_enabled() {
344 return $this->status === 'enabled';
345 }
346
347 function reset() {
348 global $wpdb;
349
350 $this->last_count = 0;
351 $this->last_access = '0000-00-00 00:00:00';
352
353 $wpdb->update( $wpdb->prefix.'redirection_items', array( 'last_count' => 0, 'last_access' => $this->last_access ), array( 'id' => $this->id ) );
354
355 RE_Log::delete_for_id( $this->id );
356 }
357
358 function show_url( $url ) {
359 return implode( '&#8203;/', explode( '/', $url ) );
360 }
361
362 function move_to( $group ) {
363 global $wpdb;
364
365 $wpdb->update( $wpdb->prefix.'redirection_items', array( 'group_id' => $group ), array( 'id' => $this->id ) );
366 }
367
368 public function enable() {
369 global $wpdb;
370
371 $this->status = 'enabled';
372 $wpdb->update( $wpdb->prefix.'redirection_items', array( 'status' => $this->status ), array( 'id' => $this->id ) );
373 }
374
375 public function disable() {
376 global $wpdb;
377
378 $this->status = 'disabled';
379 $wpdb->update( $wpdb->prefix.'redirection_items', array( 'status' => $this->status ), array( 'id' => $this->id ) );
380 }
381
382 static function actions( $action = '' ) {
383 $actions = array(
384 'url' => __( 'Redirect to URL', 'redirection' ),
385 'random' => __( 'Redirect to random post', 'redirection' ),
386 'pass' => __( 'Pass-through', 'redirection' ),
387 'error' => __( 'Error (404)', 'redirection' ),
388 'nothing' => __( 'Do nothing', 'redirection' ),
389 );
390
391 if ( $action )
392 return $actions[$action];
393 return $actions;
394 }
395
396 function match_name() {
397 return $this->match->match_name();
398 }
399
400 function type() {
401 if ( ( $this->action_type == 'url' || $this->action_type == 'error' || $this->action_type == 'random' ) && $this->action_code > 0 )
402 return $this->action_code;
403 else if ( $this->action_type == 'pass' )
404 return 'pass';
405 return '&mdash;';
406 }
407
408 public function get_id() {
409 return $this->id;
410 }
411
412 public function get_position() {
413 return $this->position;
414 }
415
416 public function get_group_id() {
417 return $this->group_id;
418 }
419
420 public function get_url() {
421 return $this->url;
422 }
423
424 public function get_title() {
425 return $this->title;
426 }
427
428 public function get_hits() {
429 return $this->last_count;
430 }
431
432 public function get_last_hit() {
433 return $this->last_access;
434 }
435
436 public function is_regex() {
437 return $this->regex ? true : false;
438 }
439
440 public function get_match_type() {
441 return $this->match_type;
442 }
443
444 public function get_action_type() {
445 return $this->action_type;
446 }
447
448 public function get_action_code() {
449 return intval( $this->action_code );
450 }
451
452 public function get_action_data() {
453 return $this->action_data;
454 }
455 }
456