| | 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 | */ |
| | 200 | function 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 | |