How can I code my plugin to safely modify .htaccess?

I want to add rules to .htaccess from within a plugin without upsetting the WP core permalink rules or rules that other plugins have added.

(My aim is to block scraping of fonts by checking the referer of any requests to font files. I know this isn’t high security, it’s just necessary to comply with font licensing.)

While I could write PHP to read and write to the file, it seems that there’s a lot of scope for breaking a site if I’m not extremely careful, so wondered if there’s already a clean way to work with .htaccess from within WP.

1 Answer
1

/wp-admin/includes/misc.php includes the function insert_with_markers() :

/**
 * Inserts an array of strings into a file (.htaccess ), placing it between
 * BEGIN and END markers.
 *
 * Replaces existing marked info. Retains surrounding
 * data. Creates file if none exists.
 *
 * @since 1.5.0
 *
 * @param string       $filename  Filename to alter.
 * @param string       $marker    The marker to alter.
 * @param array|string $insertion The new content to insert.
 * @return bool True on write success, false on failure.
 */
function insert_with_markers( $filename, $marker, $insertion ) {

insert_with_markers() checks whether the file exists & is writable, creating it if necessary. It inserts your data into the file between # BEGIN and # END markers, replacing any lines that already exist between those markers. You can pass it an array of lines or a string with line breaks. Make sure your marker name is unique to avoid clashing with WP core or other plugins.

In the same core file, save_mod_rewrite_rules() shows how WP sets up $filename, $marker & $insertion for the default permalink rules, so stealing heavily from that function:

if ( is_multisite() ) {
    // I'm not going to go here
} else {
    // Ensure get_home_path() is declared.
    require_once( ABSPATH . 'wp-admin/includes/file.php' );

    $home_path     = get_home_path();
    $htaccess_file = $home_path . '.htaccess';

    $lines = array(
        '# These are',
        '# the lines',
        '# I want to add',
    );

    if ( insert_with_markers( $htaccess_file, 'wpse_331608', $lines ) ) {
        // Celebrate your success
    } else {
        // Deal with your failure
    }
}

If your rules are for rewrites, then WP also has a helper function to check you are using Apache with mod_rewrite enabled:

if ( got_mod_rewrite() ) {
    if ( insert_with_markers( $htaccess_file, 'wpse_331608', $lines ) ) {
        // Celebrate your success
    } else {
        // Deal with your failure
    }
}

Leave a Comment