WordPress.org

Plugin Directory

Changeset 622832


Ignore:
Timestamp:
11/09/12 04:25:00 (18 months ago)
Author:
tlovett1
Message:

Version 1.5

Location:
safe-redirect-manager/trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • safe-redirect-manager/trunk/readme.txt

    r613913 r622832  
    44Requires at least: 3.1 
    55Tested up to: 3.4.2 
    6 Stable tag: 1.4.2 
     6Stable tag: 1.5 
    77 
    88Safely and easily manage your website's HTTP redirects. 
     
    2424 
    2525== Changelog == 
     26 
     27= 1.5 (Nov. 7 2012) = 
     28* Regular expressions allowed in redirects 
     29* New filter 'srm_registered_redirects' allows you to conditionally unset redirects based on context, user permissions, etc. Thanks [jtsternberg](https://github.com/jtsternberg) for the pull request. 
    2630 
    2731= 1.4.2 (Oct. 17, 2012) = 
  • safe-redirect-manager/trunk/safe-redirect-manager.php

    r613913 r622832  
    55Description: Easily and safely manage HTTP redirects. 
    66Author: Taylor Lovett (10up LLC), VentureBeat 
    7 Version: 1.4.2 
     7Version: 1.5 
    88Author URI: http://www.10up.com 
    99 
     
    2727 
    2828class SRM_Safe_Redirect_Manager { 
    29      
     29 
    3030    public $redirect_post_type = 'redirect_rule'; 
    3131    private $redirect_nonce_name = 'srm_redirect_nonce'; 
    3232    private $redirect_nonce_action = 'srm-save-redirect-meta'; 
    33      
     33 
    3434    public $meta_key_redirect_from = '_redirect_rule_from'; 
    3535    public $meta_key_redirect_to = '_redirect_rule_to'; 
    3636    public $meta_key_redirect_status_code = '_redirect_rule_status_code'; 
    37      
     37    public $meta_key_enable_redirect_from_regex = '_redirect_rule_from_regex'; 
     38 
    3839    public $cache_key_redirects = '_srm_redirects'; 
    39      
     40 
    4041    public $valid_status_codes = array( 301, 302, 303, 403, 404 ); 
    41      
     42 
    4243    private $whitelist_hosts = array(); 
    43      
     44 
    4445    public $default_max_redirects = 150; 
    45      
     46 
    4647    /** 
    4748     * Sets up redirect manager 
     
    6162        add_action( 'transition_post_status', array( $this, 'action_transition_post_status' ), 10, 3 ); 
    6263        add_filter( 'post_updated_messages', array( $this, 'filter_redirect_updated_messages' ) ); 
    63         add_action( 'admin_notices', array( $this, 'action_redirect_chain_alert' ) );    
     64        add_action( 'admin_notices', array( $this, 'action_redirect_chain_alert' ) ); 
    6465        add_filter( 'the_title', array( $this, 'filter_admin_title' ), 100, 2 ); 
    6566        add_filter( 'bulk_actions-' . 'edit-redirect_rule', array( $this, 'filter_bulk_actions' ) ); 
     
    6768        add_action( 'admin_print_styles-post.php', array( $this, 'action_print_logo_css' ), 10, 1 ); 
    6869        add_action( 'admin_print_styles-post-new.php', array( $this, 'action_print_logo_css' ), 10, 1 ); 
    69          
     70 
    7071        // Search filters 
    7172        add_filter( 'posts_join', array( $this, 'filter_search_join' ) ); 
     
    7374        add_filter( 'posts_distinct', array( $this, 'filter_search_distinct' ) ); 
    7475    } 
    75      
     76 
    7677    /** 
    7778     * Join posts table with postmeta table on search 
     
    8586        if ( $this->redirect_post_type != get_query_var( 'post_type' ) ) 
    8687            return $join; 
    87          
     88 
    8889        global $wpdb; 
    89          
     90 
    9091        $s = get_query_var( 's' ); 
    9192        if ( ! empty( $s ) ) { 
     
    9495        return $join; 
    9596    } 
    96      
     97 
    9798    /** 
    9899     * Return distinct search results 
     
    106107        if ( $this->redirect_post_type != get_query_var( 'post_type' ) ) 
    107108            return $distinct; 
    108          
     109 
    109110        return 'DISTINCT'; 
    110111    } 
    111      
     112 
    112113    /** 
    113114     * Join posts table with postmeta table on search 
     
    121122        if ( $this->redirect_post_type != get_query_var( 'post_type' ) || ! is_search() || empty( $where ) ) 
    122123            return $where; 
    123          
     124 
    124125        $exact = get_query_var( 'exact' ); 
    125126        $n = ( ! empty( $exact ) ) ? '' : '%'; 
     
    129130        $terms = $this->get_search_terms(); 
    130131        $search .= '('; 
    131          
     132 
    132133        // we check the meta values against each term in the search 
    133134        foreach ( $terms as $term ) { 
    134             $search .= $seperator;   
    135             $search .= sprintf( "( ( m.meta_value LIKE '%s%s%s' AND m.meta_key = '%s') OR ( m.meta_value LIKE '%s%s%s' AND m.meta_key = '%s') )", $n, $term, $n, $this->meta_key_redirect_from, $n, $term, $n, $this->meta_key_redirect_to );        
     135            $search .= $seperator; 
     136            $search .= sprintf( "( ( m.meta_value LIKE '%s%s%s' AND m.meta_key = '%s') OR ( m.meta_value LIKE '%s%s%s' AND m.meta_key = '%s') )", $n, $term, $n, $this->meta_key_redirect_from, $n, $term, $n, $this->meta_key_redirect_to ); 
    136137            $seperator = ' OR '; 
    137138        } 
    138          
     139 
    139140        $search .= ')'; 
    140          
     141 
    141142        $where = preg_replace( '/\(\(\(.*?\)\)\)/is', '((' . $search . '))', $where ); 
    142          
     143 
    143144        return $where; 
    144145    } 
    145      
     146 
    146147    /** 
    147148     * Get an array of search terms 
     
    160161        return $search_terms; 
    161162    } 
    162      
     163 
    163164    /** 
    164165     * Swap tools logo for plugin logo 
     
    179180                    display: none; 
    180181                } 
     182                #srm<?php echo $this->meta_key_redirect_from; ?> { 
     183                    width: 60%; 
     184                } 
    181185            </style> 
    182186        <?php 
    183187        } 
    184188    } 
    185      
     189 
    186190    /** 
    187191     * Removes bulk actions from post manager 
     
    193197        return array(); 
    194198    } 
    195      
     199 
    196200    /** 
    197201     * Creates a redirect post, this function will be useful for import/exports scripts 
     
    208212        $sanitized_redirect_to = $this->sanitize_redirect_to( $redirect_to ); 
    209213        $sanitized_status_code = absint( $status_code ); 
    210          
     214 
    211215        // check and make sure no parameters are empty or invalid after sanitation 
    212216        if ( empty( $sanitized_redirect_from ) || empty( $sanitized_redirect_to ) || ! in_array( $sanitized_status_code, $this->valid_status_codes ) ) 
    213217            return 0; 
    214          
     218 
    215219        // create the post 
    216220        $post_args = array( 
     
    219223            'post_author' => 1 
    220224        ); 
    221          
     225 
    222226        $post_id = wp_insert_post(  $post_args ); 
    223          
     227 
    224228        if ( 0 >= $post_id ) 
    225229            return 0; 
    226          
     230 
    227231        // update the posts meta info 
    228232        update_post_meta( $post_id, $this->meta_key_redirect_from, $sanitized_redirect_from ); 
    229233        update_post_meta( $post_id, $this->meta_key_redirect_to, $sanitized_redirect_to ); 
    230234        update_post_meta( $post_id, $this->meta_key_redirect_status_code, $sanitized_status_code ); 
    231          
     235 
    232236        // We need to update the cache after creating this redirect 
    233237        $this->update_redirect_cache(); 
    234          
     238 
    235239        return $post_id; 
    236240    } 
    237      
     241 
    238242    /** 
    239243     * Whether or not this is an admin page specific to the plugin 
     
    244248     */ 
    245249    private function is_plugin_page() { 
    246         return (bool) ( get_post_type() == $this->redirect_post_type || ( isset( $_GET['post_type'] ) && $this->redirect_post_type == $_GET['post_type'] ) );    
    247     }   
    248      
     250        return (bool) ( get_post_type() == $this->redirect_post_type || ( isset( $_GET['post_type'] ) && $this->redirect_post_type == $_GET['post_type'] ) ); 
     251    } 
     252 
    249253    /** 
    250254     * Echoes admin message if redirect chains exist 
     
    257261        global $hook_suffix; 
    258262        if ( $this->is_plugin_page() ) { 
    259          
     263 
    260264        /** 
    261265         * check_for_possible_redirect_loops() runs in best case Theta(n^2) so if you have 100 redirects, this method 
     
    280284        } 
    281285    } 
    282      
     286 
    283287    /** 
    284288     * Returns true if max redirects have been reached 
     
    292296            $redirects = $this->update_redirect_cache(); 
    293297        } 
    294          
     298 
    295299        $max_redirects = apply_filters( 'srm_max_redirects', $this->default_max_redirects ); 
    296          
     300 
    297301        return ( count( $redirects ) >= $max_redirects ); 
    298302    } 
    299      
     303 
    300304    /** 
    301305     * Check for potential redirect loops or chains 
     
    309313            $redirects = $this->update_redirect_cache(); 
    310314        } 
    311          
     315 
    312316        $current_url = parse_url( home_url() ); 
    313317        $this_host = ( is_array( $current_url ) && ! empty( $current_url['host'] ) ) ? $current_url['host'] : ''; 
    314          
     318 
    315319        foreach ( $redirects as $redirect ) { 
    316320            $redirect_from = $redirect['redirect_from']; 
    317              
     321 
    318322            // check redirect from against all redirect to's 
    319323            foreach ( $redirects as $compare_redirect ) { 
    320324                $redirect_to = $compare_redirect['redirect_to']; 
    321                  
     325 
    322326                $redirect_url = parse_url( $redirect_to ); 
    323327                $redirect_host = ( is_array( $redirect_url ) && ! empty( $redirect_url['host'] ) ) ? $redirect_url['host'] : ''; 
    324                  
     328 
    325329                // check if we are redirecting locally 
    326330                if ( empty( $redirect_host ) || $redirect_host == $this_host ) { 
     
    331335                    else 
    332336                        $redirect_to_url = preg_replace( '/(http:\/\/|https:\/\/|www\.)/i', '', $redirect_to_url ); 
    333                      
     337 
    334338                    // possible loop/chain found 
    335339                    if ( $redirect_to_url == $redirect_from_url ) 
     
    338342            } 
    339343        } 
    340          
     344 
    341345        return false; 
    342346    } 
    343      
     347 
    344348    /** 
    345349     * Filters title out for redirect from in post manager 
     
    354358        if ( ! is_admin() || false === ( $redirect = get_post( $post_id ) ) || $redirect->post_type != $this->redirect_post_type ) 
    355359            return $title; 
    356          
     360 
    357361        $redirect_from = get_post_meta( $post_id, $this->meta_key_redirect_from, true ); 
    358362        if ( ! empty( $redirect_from ) ) 
    359363            return $redirect_from; 
    360          
     364 
    361365        return $title; 
    362366    } 
    363      
     367 
    364368    /** 
    365369     * Customizes updated messages for redirects 
     
    372376    public function filter_redirect_updated_messages( $messages ) { 
    373377        global $post, $post_ID; 
    374        
     378 
    375379        $messages[$this->redirect_post_type] = array( 
    376380          0 => '', // Unused. Messages start at index 1. 
     
    389393          10 => sprintf( __( 'Redirect rule draft updated.', 'safe-redirect-manager' ), esc_url( add_query_arg( 'preview', 'true', get_permalink( $post_ID ) ) ) ), 
    390394        ); 
    391        
     395 
    392396        return $messages; 
    393397    } 
    394      
     398 
    395399    /** 
    396400     * Clear redirect cache if appropriate post type is transitioned 
     
    406410        if ( ! is_object( $post ) ) 
    407411            return; 
    408          
     412 
    409413        // recreate redirect cache 
    410414        if ( $this->redirect_post_type == $post->post_type ) { 
     
    413417        } 
    414418    } 
    415      
     419 
    416420    /** 
    417421     * Displays custom columns on redirect manager screen 
     
    430434        } 
    431435    } 
    432      
     436 
    433437    /** 
    434438     * Add new columns to manage redirect screen 
     
    441445        $columns['srm' . $this->meta_key_redirect_to] = __( 'Redirect To', 'safe-redirect-manager' ); 
    442446        $columns['srm'. $this->meta_key_redirect_status_code] = __( 'HTTP Status Code', 'safe-redirect-manager' ); 
    443          
     447 
    444448        // Change the title column 
    445449        $columns['title'] = __( 'Redirect From', 'safe-redirect-manager' ); 
    446          
     450 
    447451        // Move date column to the back 
    448452        unset( $columns['date'] ); 
    449453        $columns['date'] = __( 'Date', 'safe-redirect-manager' ); 
    450          
     454 
    451455        // get rid of checkboxes 
    452456        unset( $columns['cb'] ); 
    453          
     457 
    454458        return $columns; 
    455459    } 
    456      
     460 
    457461    /** 
    458462     * Saves meta info for redirect rules 
     
    466470        if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || ! current_user_can( 'edit_post', $post_id ) || 'revision' == get_post_type( $post_id ) ) 
    467471            return; 
    468          
     472 
    469473        // Update post meta for redirect rules 
    470474        if ( ! empty( $_POST[$this->redirect_nonce_name] ) && wp_verify_nonce( $_POST[$this->redirect_nonce_name], $this->redirect_nonce_action ) ) { 
    471              
     475 
     476            if ( ! empty( $_POST['srm' . $this->meta_key_enable_redirect_from_regex] ) ) { 
     477                $allow_regex = (bool) $_POST['srm' . $this->meta_key_enable_redirect_from_regex]; 
     478                update_post_meta( $post_id, $this->meta_key_enable_redirect_from_regex, $allow_regex ); 
     479            } else { 
     480                $allow_regex = false; 
     481                delete_post_meta( $post_id, $this->meta_key_enable_redirect_from_regex ); 
     482            } 
     483         
    472484            if ( ! empty( $_POST['srm' . $this->meta_key_redirect_from] ) ) { 
    473                 update_post_meta( $post_id, $this->meta_key_redirect_from, $this->sanitize_redirect_from( $_POST['srm' . $this->meta_key_redirect_from] ) ); 
     485                update_post_meta( $post_id, $this->meta_key_redirect_from, $this->sanitize_redirect_from( $_POST['srm' . $this->meta_key_redirect_from], $allow_regex ) ); 
    474486            } else { 
    475487                delete_post_meta( $post_id, $this->meta_key_redirect_from ); 
    476488            } 
    477              
     489 
    478490            if ( ! empty( $_POST['srm' . $this->meta_key_redirect_to] ) ) { 
    479491                update_post_meta( $post_id, $this->meta_key_redirect_to, $this->sanitize_redirect_to( $_POST['srm' . $this->meta_key_redirect_to] ) ); 
     
    481493                delete_post_meta( $post_id, $this->meta_key_redirect_to ); 
    482494            } 
    483              
     495 
    484496            if ( ! empty( $_POST['srm' . $this->meta_key_redirect_status_code] ) ) { 
    485497                update_post_meta( $post_id, $this->meta_key_redirect_status_code, absint( $_POST['srm' . $this->meta_key_redirect_status_code] ) ); 
     
    487499                delete_post_meta( $post_id, $this->meta_key_redirect_status_code ); 
    488500            } 
    489              
     501 
    490502            /** 
    491503             * This fixes an important bug where the redirect cache was not up-to-date. Previously the cache was only being 
     
    496508        } 
    497509    } 
    498      
     510 
    499511    /** 
    500512     * Registers post types for plugin 
     
    516528            'search_items' => __( 'Search Redirects', 'safe-redirect-manager' ), 
    517529            'not_found' =>  __( 'No redirect rules found.', 'safe-redirect-manager' ), 
    518             'not_found_in_trash' => __( 'No redirect rules found in trash.', 'safe-redirect-manager' ),  
     530            'not_found_in_trash' => __( 'No redirect rules found in trash.', 'safe-redirect-manager' ), 
    519531            'parent_item_colon' => '', 
    520532            'menu_name' => __( 'Safe Redirect Manager', 'safe-redirect-manager' ) 
     
    531543            'read_private_posts' => $redirect_capability 
    532544        ); 
    533          
     545 
    534546        $redirect_args = array( 
    535547          'labels' => $redirect_labels, 
    536548          'public' => false, 
    537549          'publicly_queryable' => true, 
    538           'show_ui' => true,  
    539           'show_in_menu' => 'tools.php',  
     550          'show_ui' => true, 
     551          'show_in_menu' => 'tools.php', 
    540552          'query_var' => false, 
    541553          'rewrite' => false, 
    542554          'capability_type' => 'post', 
    543555          'capabilities' => $capabilities, 
    544           'has_archive' => false,  
     556          'has_archive' => false, 
    545557          'hierarchical' => false, 
    546558          'register_meta_box_cb' => array( $this, 'action_redirect_rule_metabox' ), 
    547559          'menu_position' => 80, 
    548560          'supports' => array( '' ) 
    549         );  
     561        ); 
    550562        register_post_type( $this->redirect_post_type, $redirect_args ); 
    551563    } 
    552      
     564 
    553565    /** 
    554566     * Registers meta boxes for redirect rule post type 
     
    561573        add_meta_box( 'redirect_settings', __( 'Redirect Settings', 'safe-redirect-manager' ), array( $this, 'redirect_rule_metabox' ), $this->redirect_post_type, 'normal', 'core' ); 
    562574    } 
    563      
     575 
    564576    /** 
    565577     * Echoes HTML for redirect rule meta box 
    566      *  
     578     * 
    567579     * @since 1.0 
    568580     * @param object $post 
     
    572584    public function redirect_rule_metabox( $post ) { 
    573585        wp_nonce_field( $this->redirect_nonce_action, $this->redirect_nonce_name ); 
    574          
     586 
    575587        $redirect_from = get_post_meta( $post->ID, $this->meta_key_redirect_from, true ); 
    576588        $redirect_to = get_post_meta( $post->ID, $this->meta_key_redirect_to, true ); 
    577589        $status_code = get_post_meta( $post->ID, $this->meta_key_redirect_status_code, true ); 
     590        $enable_regex = get_post_meta( $post->ID, $this->meta_key_enable_redirect_from_regex, true ); 
    578591        if ( empty( $status_code ) ) 
    579592            $status_code = 302; 
     
    581594        <p> 
    582595            <label for="srm<?php echo $this->meta_key_redirect_from; ?>"><?php _e( 'Redirect From:', 'safe-redirect-manager' ); ?></label><br /> 
    583             <input class="widefat" type="text" name="srm<?php echo $this->meta_key_redirect_from; ?>" id="srm<?php echo $this->meta_key_redirect_from; ?>" value="<?php echo esc_attr( $redirect_from ); ?>" /><br /> 
    584             <p class="description"><?php _e( "This path should be relative to the root of this WordPress installation (or the sub-site, if you are running a multi-site). Appending a (*) wildcard character will match all requests with the base.", 'safe-redirect-manager' ); ?></p> 
     596            <input type="text" name="srm<?php echo $this->meta_key_redirect_from; ?>" id="srm<?php echo $this->meta_key_redirect_from; ?>" value="<?php echo esc_attr( $redirect_from ); ?>" />  
     597            <input type="checkbox" name="srm<?php echo $this->meta_key_enable_redirect_from_regex; ?>" id="srm<?php echo $this->meta_key_enable_redirect_from_regex; ?>" <?php checked( true, (bool) $enable_regex ); ?> value="1" /> 
     598            <label for="srm<?php echo $this->meta_key_enable_redirect_from_regex; ?>"><?php _e( 'Enable Regular Expressions (advanced)', 'safe-redirect-manager' ); ?></label><br /> 
     599            <p class="description"><?php _e( "This path should be relative to the root of this WordPress installation (or the sub-site, if you are running a multi-site). Appending a (*) wildcard character will match all requests with the base. Warning: Enabling regular expressions will disable wildcards and completely change the way the * symbol is interpretted.", 'safe-redirect-manager' ); ?></p> 
    585600        </p> 
    586          
     601 
    587602        <p> 
    588603            <label for="srm<?php echo $this->meta_key_redirect_to; ?>"><?php _e( 'Redirect To:', 'safe-redirect-manager' ); ?></label><br /> 
     
    590605            <p class="description"><?php _e( "This can be a URL or a path relative to the root of your website (not your WordPress installation). Ending with a (*) wildcard character will append the request match to the redirect.", 'safe-redirect-manager'); ?></p> 
    591606        </p> 
    592          
     607 
    593608        <p> 
    594             <label for="srm<?php echo $this->meta_key_redirect_status_code; ?>"><?php _e( 'HTTP Status Code:', 'safe-redirect-manager' ); ?></label>  
     609            <label for="srm<?php echo $this->meta_key_redirect_status_code; ?>"><?php _e( 'HTTP Status Code:', 'safe-redirect-manager' ); ?></label> 
    595610            <select name="srm<?php echo $this->meta_key_redirect_status_code; ?>" id="srm<?php echo $this->meta_key_redirect_status_code; ?>"> 
    596611                <?php foreach ( $this->valid_status_codes as $code ) : ?> 
     
    602617    <?php 
    603618    } 
    604      
     619 
    605620    /** 
    606621     * Localize plugin 
     
    613628        load_plugin_textdomain( 'safe-redirect-manager', false, dirname( plugin_basename( __FILE__ ) ) . '/languages/' ); 
    614629    } 
    615      
     630 
    616631    /** 
    617632     * Apply whitelisted hosts to allowed_redirect_hosts filter 
     
    622637     */ 
    623638    public function filter_allowed_redirect_hosts( $content ) { 
    624          
     639 
    625640        foreach ( $this->whitelist_hosts as $host ) { 
    626641            $without_www = preg_replace( '/^www\./i', '', $host ); 
    627642            $with_www = 'www.' . $without_www; 
    628              
     643 
    629644            if ( ! in_array( $without_www, $content ) ) $content[] = $without_www; 
    630645            if ( ! in_array( $with_www, $content ) ) $content[] = $with_www; 
    631646        } 
    632          
     647 
    633648        return $content; 
    634649    } 
    635      
     650 
    636651    /** 
    637652     * Force update on the redirect cache and return cache 
     
    644659        global $post; 
    645660        $old_post = $post; 
    646          
     661 
    647662        $args = array( 
    648663            'posts_per_page' => 1000, 
     
    654669        $redirect_query = new WP_Query( $args ); 
    655670        $redirect_cache = array(); 
    656          
     671 
    657672        if ( $redirect_query->have_posts() ) { 
    658673            while ( $redirect_query->have_posts() ) { 
    659674                $redirect_query->the_post(); 
    660                  
     675 
    661676                $redirect_from = get_post_meta( get_the_ID(), $this->meta_key_redirect_from, true ); 
    662677                $redirect_to = get_post_meta( get_the_ID(), $this->meta_key_redirect_to, true ); 
    663678                $status_code = get_post_meta( get_the_ID(), $this->meta_key_redirect_status_code, true ); 
    664                  
     679                $enable_regex = get_post_meta( get_the_ID(), $this->meta_key_enable_redirect_from_regex, true ); 
     680 
    665681                if ( ! empty( $redirect_from ) && ! empty( $redirect_to ) ) { 
    666682                    $redirect_cache[] = array( 
    667683                        'redirect_from' => $redirect_from, 
    668684                        'redirect_to' => $redirect_to, 
    669                         'status_code' => absint( $status_code ) 
     685                        'status_code' => absint( $status_code ), 
     686                        'enable_regex' => (bool) $enable_regex 
    670687                    ); 
    671688                } 
     
    674691        $post = $old_post; 
    675692        set_transient( $this->cache_key_redirects, $redirect_cache ); 
    676          
     693 
    677694        return $redirect_cache; 
    678695    } 
    679      
     696 
    680697    /** 
    681698     * Check current url against redirects 
     
    686703     */ 
    687704    public function action_parse_request() { 
    688          
     705 
    689706        // get redirects from cache or recreate it 
    690707        if ( false === ( $redirects = get_transient( $this->cache_key_redirects ) ) ) { 
    691708            $redirects = $this->update_redirect_cache(); 
    692709        } 
    693          
     710 
    694711        // If we have no redirects, there is no need to continue 
    695712        if ( empty( $redirects ) ) 
    696713            return; 
    697          
     714 
    698715        // get requested path and add a / before it 
    699716        $requested_path = sanitize_text_field( $_SERVER['REQUEST_URI'] ); 
    700          
     717 
    701718        /** 
    702719         * If WordPress resides in a directory that is not the public root, we have to chop 
     
    704721         */ 
    705722        $parsed_site_url = parse_url( site_url() ); 
    706         if ( '/' != $parsed_site_url['path'] ) { 
     723        if ( isset( $parsed_site_url['path'] ) && '/' != $parsed_site_url['path'] ) { 
    707724            $requested_path = preg_replace( '@' . $parsed_site_url['path'] . '@i', '', $requested_path, 1 ); 
    708725        } 
    709          
    710         foreach ( $redirects as $redirect ) { 
    711              
     726 
     727        // Allow redirects to be filtered 
     728        $redirects = apply_filters( 'srm_registered_redirects', $redirects, $requested_path ); 
     729 
     730        foreach ( (array)$redirects as $redirect ) { 
     731 
    712732            $redirect_from = untrailingslashit( $redirect['redirect_from'] ); 
    713733            if ( empty( $redirect_from ) ) 
    714734                $redirect_from = '/'; // this only happens in the case where there is a redirect on the root 
    715                  
     735 
    716736            $redirect_to = $redirect['redirect_to']; 
    717737            $status_code = $redirect['status_code']; 
     738            $enable_regex = ( isset( $redirect['enable_regex'] ) ) ? $redirect['enable_regex'] : false; 
    718739 
    719740            if ( apply_filters( 'srm_case_insensitive_redirects', true ) ) { 
     
    721742                $redirect_from = strtolower( $redirect_from ); 
    722743            } 
    723              
     744 
    724745            // check if requested path is the same as the redirect from path 
    725             $matched_path = ( untrailingslashit( $requested_path ) == $redirect_from ); 
    726              
    727             // check if the redirect_from ends in a wildcard 
    728             if ( !$matched_path && (strrpos( $redirect_from, '*' ) == strlen( $redirect_from ) - 1) ) { 
    729                 $wildcard_base = substr( $redirect_from, 0, strlen( $redirect_from ) - 1 ); 
    730  
    731                 // mark as match if requested path matches the base of the redirect from 
    732                 $matched_path = (substr( $requested_path, 0, strlen( $wildcard_base ) ) == $wildcard_base); 
    733                 if ( (strrpos( $redirect_to, '*' ) == strlen( $redirect_to ) - 1 ) ) { 
    734                     $redirect_to = rtrim( $redirect_to, '*' ) . ltrim( substr( $requested_path, strlen( $wildcard_base ) ), '/' ); 
     746            if ( $enable_regex ) { 
     747                $matched_path = preg_match( '@' . $redirect_from . '@', $requested_path ); 
     748            } else { 
     749                $matched_path = ( untrailingslashit( $requested_path ) == $redirect_from ); 
     750 
     751                // check if the redirect_from ends in a wildcard 
     752                if ( !$matched_path && (strrpos( $redirect_from, '*' ) === strlen( $redirect_from ) - 1) ) { 
     753                    $wildcard_base = substr( $redirect_from, 0, strlen( $redirect_from ) - 1 ); 
     754 
     755                    // mark as match if requested path matches the base of the redirect from 
     756                    $matched_path = (substr( $requested_path, 0, strlen( $wildcard_base ) ) == $wildcard_base); 
     757                    if ( (strrpos( $redirect_to, '*' ) == strlen( $redirect_to ) - 1 ) ) { 
     758                        $redirect_to = rtrim( $redirect_to, '*' ) . ltrim( substr( $requested_path, strlen( $wildcard_base ) ), '/' ); 
     759                    } 
    735760                } 
    736761            } 
    737762 
    738             if ( $matched_path ) {       
     763            if ( $matched_path ) { 
    739764                // whitelist redirect to host if necessary 
    740765                $parsed_redirect = parse_url( $redirect_to ); 
     
    743768                    add_filter( 'allowed_redirect_hosts' , array( $this, 'filter_allowed_redirect_hosts' ) ); 
    744769                } 
    745                  
     770 
    746771                header("X-Safe-Redirect-Manager: true"); 
    747                  
     772 
    748773                // if we have a valid status code, then redirect with it 
    749774                if ( in_array( $status_code, $this->valid_status_codes ) ) 
     
    755780        } 
    756781    } 
    757      
     782 
    758783    /** 
    759784     * Sanitize redirect to path 
     
    769794    public function sanitize_redirect_to( $path ) { 
    770795        $path = trim( $path ); 
    771          
     796 
    772797        if (  preg_match( '/^www\./i', $path ) ) 
    773798            $path = 'http://' . $path; 
    774          
     799 
    775800        if ( ! preg_match( '/^https?:\/\//i', $path ) ) 
    776801            if ( strpos( $path, '/' ) !== 0 ) 
    777802                $path = '/' . $path; 
    778          
     803 
    779804        return esc_url_raw( $path ); 
    780805    } 
    781      
     806 
    782807    /** 
    783808     * Sanitize redirect from path 
     
    785810     * @since 1.0 
    786811     * @param string $path 
     812     * @param boolean $allow_regex 
    787813     * @uses esc_url_raw 
    788814     * @return string 
    789815     */ 
    790     public function sanitize_redirect_from( $path ) { 
    791          
     816    public function sanitize_redirect_from( $path, $allow_regex = false ) { 
     817 
    792818        $path = trim( $path ); 
    793          
     819 
    794820        if ( empty( $path ) ) 
    795821                return ''; 
    796          
     822 
    797823        // dont accept paths starting with a . 
    798         if ( strpos( $path, '.' ) === 0 ) 
     824        if ( ! $allow_regex && strpos( $path, '.' ) === 0 ) 
    799825            return ''; 
    800          
     826 
    801827        // turn path in to absolute 
    802828        if ( preg_match( '/https?:\/\//i', $path ) ) 
    803829            $path = preg_replace( '/^(http:\/\/|https:\/\/)(www\.)?[^\/?]+\/?(.*)/i', '/$3', $path ); 
    804         elseif ( strpos( $path, '/' ) !== 0 ) 
     830        elseif ( ! $allow_regex && strpos( $path, '/' ) !== 0 ) 
    805831            $path = '/' . $path; 
    806          
    807         return esc_url_raw( $path ); 
     832 
     833        // the @ symbol will break our regex engine 
     834        $path = str_replace( '@', '', $path ); 
     835 
     836        return $path; 
    808837    } 
    809838} 
Note: See TracChangeset for help on using the changeset viewer.