PluginProbe
Redirection / 2.4.3
Redirection v2.4.3
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.3, at models/redirect.php

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