PluginProbe
Redirection / 2.3.16
Redirection v2.3.16
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.3.16, at models/redirect.php

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