Make WordPress Core

Ticket #41946: remove_with_markers.patch

File remove_with_markers.patch, 2.4 KB (added by sergiosanchez, 5 years ago)

Added function remove_with_markers

  • wp-admin/includes/misc.php

    diff --git a/wp-admin/includes/misc.php b/wp-admin/includes/misc.php
    index 6b46f67037..f057c11ae9 100644
    a b function insert_with_markers( $filename, $marker, $insertion ) { 
    188188        return (bool) $bytes;
    189189}
    190190
     191/**
     192 * Removes a section between BEGIN and END markers in a file (.htaccess).
     193 *
     194 * Retains surrounding data. Creates file if none exists.
     195 *
     196 * @param string       $filename  Filename to alter.
     197 * @param string       $marker    The marker to alter.
     198 * @return bool True on write success, false on failure.
     199 */
     200function remove_with_markers( $filename, $marker ) {
     201        if ( ! file_exists( $filename ) ) {
     202                if ( ! is_writable( dirname( $filename ) ) ) {
     203                        return false;
     204                }
     205        } elseif ( ! is_writeable( $filename ) ) {
     206                return false;
     207        }
     208
     209        $start_marker = "# BEGIN {$marker}";
     210        $end_marker   = "# END {$marker}";
     211
     212        $fp = fopen( $filename, 'r+' );
     213        if ( ! $fp ) {
     214                return false;
     215        }
     216
     217        // Attempt to get a lock. If the filesystem supports locking, this will block until the lock is acquired.
     218        flock( $fp, LOCK_EX );
     219
     220        $lines = array();
     221        while ( ! feof( $fp ) ) {
     222                $lines[] = rtrim( fgets( $fp ), "\r\n" );
     223        }
     224
     225        // Split out the existing file into the preceding lines, and those that appear after the marker.
     226        $pre_lines    = $post_lines = array();
     227        $found_marker = $found_end_marker = false;
     228        foreach ( $lines as $line ) {
     229                if ( ! $found_marker && false !== strpos( $line, $start_marker ) ) {
     230                        $found_marker = true;
     231                        continue;
     232                } elseif ( ! $found_end_marker && false !== strpos( $line, $end_marker ) ) {
     233                        $found_end_marker = true;
     234                        continue;
     235                }
     236                if ( ! $found_marker ) {
     237                        $pre_lines[] = $line;
     238                } elseif ( $found_marker && $found_end_marker ) {
     239                        $post_lines[] = $line;
     240                }
     241        }
     242
     243        // Check if both markers were found.
     244        if ( ! $found_marker || ! $found_end_marker ) {
     245                flock( $fp, LOCK_UN );
     246                fclose( $fp );
     247
     248                return true;
     249        }
     250
     251        // Generate the new file data.
     252        $new_file_data = implode(
     253                "\n",
     254                array_merge(
     255                        $pre_lines,
     256                        $post_lines
     257                )
     258        );
     259
     260        // Write to the start of the file, and truncate it to that length.
     261        fseek( $fp, 0 );
     262        $bytes = fwrite( $fp, $new_file_data );
     263        if ( $bytes ) {
     264                ftruncate( $fp, ftell( $fp ) );
     265        }
     266        fflush( $fp );
     267        flock( $fp, LOCK_UN );
     268        fclose( $fp );
     269
     270        return (bool) $bytes;
     271}
     272
    191273/**
    192274 * Updates the htaccess file with the current rules if it is writable.
    193275 *