WordPress.org

Forums

[Plugin/Hack: Piggyback Rewrite Rule] (1 post)

  1. k4st
    Member
    Posted 7 years ago #

    Sometimes it's nice to just be able to force a pattern into the wordpress rewrite class and the database. This plugin will get that done for you. Enjoy.

    <?php
    /*
    Plugin Name: Piggyback Rewrite Rules
    Plugin URI: http://ioreader.com
    Description: Force rewrite rules into the database and the WP_Rewrite class.
    Author: Peter Goodman
    */
    
    // yikes!
    !defined('WP_MAIN_DIR') &&
        define('WP_MAIN_DIR', dirname(dirname(dirname(__FILE__))));
    
    /**
     * Piggyback a rule into the WP_Rewrite class, even if it doesn't exist in the
     * database (yet). Note: do not anchor regular expression rules to the start of
     * a subject. Anchor them to the end of one, ie: regex here $. Do not put any
     * delimiters or modifiers in the regular expression. When accessing subpattern
     * matches in $location, use: $matches[x] where 'x' is the numbered subpattern.
     * The first subpattern can be referenced by $matches[1].
     * @author Peter Goodman
     */
    function piggyback_rewrite_rule($regex = '', $location = '') {
        static $rules = array();
    
        if(!empty($regex)) {
            $rules[$regex] = $location;
            return;
        }
    
        return $rules;
    }
    
    /**
     * Add in the piggybacked rules.
     * @author Peter Goodman
     * @internal
     */
    function piggyback_rewrite_rules() {
        global $wp_rewrite;
    
        // this has likely been cached already
        $rules =& get_option('rewrite_rules');
        $changed = FALSE;
        $force = FALSE; // for debugging
    
        // go over the piggybacked rules and add them in if necessary
        foreach(piggyback_rewrite_rule() as $regex => $location) {
    
            // make sure it gets into the database
            if(!isset($rules[$regex]) || $force) {
                $rules[$regex] = $location;
                $changed = TRUE;
            }
    
            // make sure it shows up in the class as well, this is less important
            // we put it into the extra_rules as well to make sure it will live on
            // if we rewrite the rules.
            $wp_rewrite->rules[$regex] = $location;
            $wp_rewrite->extra_rules[$regex] = $location;
        }
    
        // update the db options
        if($changed || $force) {
    
            // discard any changed (and no longer useful) rules that no longer
            // need to be in the database
            $wp_rewrite->rewrite_rules();
            krsort($wp_rewrite->rules);
            update_option('rewrite_rules', $wp_rewrite->rules);
    
            // if .htaccess doesn't exist for some reason, create it.
            $htaccess = WP_MAIN_DIR .'/.htaccess';
            if(!file_exists($htaccess))
                piggyback_force_rewrite($htaccess);
        }
    }
    
    /**
     * Force a rewrite of the .htaccess file if it doesn't yet exist.
     * @author Peter Goodman
     * @internal
     */
    function piggyback_force_rewrite($htaccess_file) {
        global $wp_rewrite;
    
        $rules = $wp_rewrite->mod_rewrite_rules();
        $fp = fopen($htaccess_file, "w");
    
        // write the rules to the .htaccess
        if(is_resource($fp)) {
            fwrite($fp, $rules);
            fclose($fp);
        }
    }
    
    // could use add_action, but it just calls add_filter and so we will ignore
    // the distinction. The priority is 1 so that it is executed *before* the
    // redirect_canonical() function
    add_filter('template_redirect', 'piggyback_rewrite_rules', 1);
    
    /**
     * Helper function for doing feeds.
     */
    function rewrite_feed($extra = '') {
        return 'index.php?&feed=$matches[1]' . $extra;
    }

Topic Closed

This topic has been closed to new replies.

About this Topic