2

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.

2

/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
    }
}
2
  • Do you have any control over where in the .htaccess file the directives are inserted? Top, bottom, before or after an existing code block, etc? – MrWhite Mar 14 '19 at 11:28
  • @MrWhite No, it just writes to the top of the file. I guess if the order of the sections in the file matters to you, then you have other problems to deal with. If your rules depend on rules in other sections, what will you do if those other sections change later on? – Andy Macaulay-Brook Mar 14 '19 at 11:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.