Skip to content
wiki.fftac.org

Htaccessmanager - Source Excerpt 01

Back to Htaccessmanager

Summary

This source excerpt preserves a bounded section of Antichrist.net/wp-content/plugins/uaix-locale-router/src/Rewrite/HtaccessManager.php so readers can inspect the evidence without opening the full source file.

**Source path:** Antichrist.net/wp-content/plugins/uaix-locale-router/src/Rewrite/HtaccessManager.php

<?php

namespace UAIXLocaleRouter\Rewrite;

use UAIXLocaleRouter\LocaleRepository;
use UAIXLocaleRouter\Plugin;

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

final class HtaccessManager {
	/**
	 * Return site-root .htaccess diagnostics for Apache and LiteSpeed repairs.
	 *
	 * @return array
	 */
	public static function htaccess_diagnostics() {
		if ( ! function_exists( 'get_home_path' ) ) {
			require_once ABSPATH . 'wp-admin/includes/file.php';
		}

		if ( ! function_exists( 'insert_with_markers' ) || ! function_exists( 'extract_from_markers' ) ) {
			require_once ABSPATH . 'wp-admin/includes/misc.php';
		}

		$server_context = self::htaccess_server_context();
		$home_path      = function_exists( 'get_home_path' ) ? (string) get_home_path() : (string) ABSPATH;
		$htaccess_path  = trailingslashit( $home_path ) . '.htaccess';
		$htaccess_dir   = dirname( $htaccess_path );
		$file_exists    = file_exists( $htaccess_path );
		$file_writable  = $file_exists ? is_writable( $htaccess_path ) : false;
		$dir_writable   = is_dir( $htaccess_dir ) && is_writable( $htaccess_dir );
		$marker_state          = self::htaccess_marker_state( $htaccess_path, self::htaccess_marker_name(), self::htaccess_marker_insert_lines(), $file_exists );
		$wordpress_marker_name = self::wordpress_htaccess_marker_name();
		$wordpress_state       = self::htaccess_marker_state( $htaccess_path, $wordpress_marker_name, self::wordpress_htaccess_marker_insert_lines(), $file_exists );
		$auto_repair           = ! empty( $server_context['supports_htaccess'] ) && function_exists( 'insert_with_markers' ) && ( ( $file_exists && $file_writable ) || ( ! $file_exists && $dir_writable ) );
		$reason                = '';
		$repair_needed         = ! $marker_state['current'] || ! $wordpress_state['current'];

		if ( empty( $server_context['supports_htaccess'] ) ) {
			$reason = __( 'Automatic .htaccess repair is available only for Apache or LiteSpeed-style .htaccess environments.', 'uaix-locale-router' );
		} elseif ( $file_exists && ! $file_writable ) {
			$reason = __( 'The site-root .htaccess file exists, but WordPress cannot write to it.', 'uaix-locale-router' );
		} elseif ( ! $file_exists && ! $dir_writable ) {
			$reason = __( 'The site-root folder is not writable, so WordPress cannot create .htaccess there.', 'uaix-locale-router' );
		} elseif ( ! function_exists( 'insert_with_markers' ) ) {
			$reason = __( 'WordPress marker utilities are not available in this runtime, so the .htaccess block must be added manually.', 'uaix-locale-router' );
		}

		return array(
			'server_label'           => $server_context['label'],
			'server_type'            => $server_context['type'],
			'server_software'        => $server_context['software'],
			'supports_htaccess'      => $server_context['supports_htaccess'],
			'path'                   => $htaccess_path,
			'directory'              => $htaccess_dir,
			'exists'                 => $file_exists,
			'file_writable'          => $file_writable,
			'directory_writable'     => $dir_writable,
			'marker_name'            => self::htaccess_marker_name(),
			'marker_present'         => $marker_state['present'],
			'marker_current'         => $marker_state['current'],
			'wordpress_marker_name'  => $wordpress_marker_name,
			'wordpress_marker_present'=> $wordpress_state['present'],
			'wordpress_marker_current'=> $wordpress_state['current'],
			'wordpress_marker_conflict'=> $wordpress_state['present'] && ! $wordpress_state['current'],
			'repair_needed'          => $repair_needed,
			'auto_repair_available'  => $auto_repair,
			'manual_reason'          => $reason,
			'manual_block'           => self::htaccess_manual_block(),
		);
	}

	/**
	 * Return marker presence and currency details for a specific .htaccess block.
	 *
	 * @param string   $htaccess_path Absolute .htaccess path.
	 * @param string   $marker_name Marker name.
	 * @param string[] $insert_lines Expected lines between marker comments.
	 * @param bool     $file_exists Whether the .htaccess file exists.
	 * @return array
	 */
	private static function htaccess_marker_state( $htaccess_path, $marker_name, array $insert_lines, $file_exists ) {
		$marker_lines = ( $file_exists && function_exists( 'extract_from_markers' ) ) ? extract_from_markers( $htaccess_path, $marker_name ) : array();
		$present      = ! empty( $marker_lines );
		$current      = $present && $marker_lines === $insert_lines;

		return array(
			'present' => $present,
			'current' => $current,
			'lines'   => $marker_lines,
		);
	}

	/**
	 * Describe the current server for .htaccess repair purposes.
	 *
	 * @return array
	 */
	private static function htaccess_server_context() {
		if ( ! function_exists( 'got_mod_rewrite' ) ) {
			require_once ABSPATH . 'wp-admin/includes/misc.php';
		}

		$software  = isset( $_SERVER['SERVER_SOFTWARE'] ) ? sanitize_text_field( wp_unslash( $_SERVER['SERVER_SOFTWARE'] ) ) : '';
		$normalized = strtolower( $software );
		$type      = 'unknown';
		$label     = __( 'Unknown server', 'uaix-locale-router' );
		$supports  = false;

		if ( false !== strpos( $normalized, 'litespeed' ) ) {
			$type     = 'litespeed';
			$label    = __( 'LiteSpeed', 'uaix-locale-router' );
			$supports = true;
		} elseif ( false !== strpos( $normalized, 'apache' ) ) {
			$type     = 'apache';
			$label    = __( 'Apache', 'uaix-locale-router' );
			$supports = true;
		} elseif ( false !== strpos( $normalized, 'nginx' ) ) {
			$type  = 'nginx';
			$label = __( 'Nginx', 'uaix-locale-router' );
		} elseif ( false !== strpos( $normalized, 'iis' ) ) {
			$type  = 'iis';
			$label = __( 'IIS', 'uaix-locale-router' );
		} elseif ( function_exists( 'got_mod_rewrite' ) && got_mod_rewrite() ) {
			$type     = 'apache-compatible';
			$label    = __( 'Apache-compatible mod_rewrite', 'uaix-locale-router' );
			$supports = true;
		}

		return array(
			'type'             => $type,
			'label'            => $label,
			'software'         => $software,
			'supports_htaccess'=> $supports,
		);
	}

	/**
	 * Return the marker name used for site-root .htaccess repairs.
	 *
	 * @return string
	 */
	public static function htaccess_marker_name() {
		return 'UAIX Locale Router';
	}

	/**
	 * Return the WordPress marker name used in site-root .htaccess.
	 *
	 * @return string
	 */
	private static function wordpress_htaccess_marker_name() {
		return 'WordPress';
	}

	/**
	 * Return the locale-aware rewrite block body for .htaccess marker insertion.
	 *
	 * @return array
	 */
	public static function htaccess_marker_body_lines() {
		$rewrite_base = self::htaccess_rewrite_base();
		$index_target = self::htaccess_index_target();
		$locale_regex = '(' . self::htaccess_enabled_locale_pattern() . ')';

		return array(
			'<IfModule mod_rewrite.c>',
			'RewriteEngine On',
			'RewriteBase ' . $rewrite_base,
			'# Keep repo instruction markdown out of the public web surface.',
			'RewriteRule (^|/).+\.(?:md|markdown)$ - [F,L,NC]',
			'RewriteRule ^' . $locale_regex . '/?$ ' . $index_target . ' [QSA,L]',
			'RewriteCond %{REQUEST_FILENAME} !-f',
			'RewriteCond %{REQUEST_FILENAME} !-d',
			'RewriteRule ^' . $locale_regex . '/(.+)$ ' . $index_target . ' [QSA,L]',
			'</IfModule>',
		);
	}

	/**
	 * Return the standard WordPress rewrite block body for the current site path.
	 *
	 * @return array
	 */
	private static function wordpress_htaccess_marker_body_lines() {
		$rewrite_base = self::htaccess_rewrite_base();
		$index_target = self::htaccess_index_target();

		return array(
			'<IfModule mod_rewrite.c>',
			'RewriteEngine On',
			'RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]',
			'RewriteBase ' . $rewrite_base,
			'RewriteRule ^index\.php$ - [L]',
			'RewriteCond %{REQUEST_FILENAME} !-f',
			'RewriteCond %{REQUEST_FILENAME} !-d',
			'RewriteRule . ' . $index_target . ' [L]',
			'</IfModule>',
		);
	}

	/**
	 * Return the comment lines WordPress writes inside marker-managed files.
	 *
	 * @return array
	 */
	private static function htaccess_marker_instruction_lines() {
		return self::htaccess_marker_instruction_lines_for( self::htaccess_marker_name() );
	}

	/**
	 * Return the comment lines WordPress writes inside a marker-managed block.
	 *
	 * @param string $marker_name Marker name.
	 * @return array
	 */
	private static function htaccess_marker_instruction_lines_for( $marker_name ) {
		$instructions = sprintf(
			/* translators: %s: marker name */
			__(
				'The directives (lines) between "BEGIN %1$s" and "END %1$s" are
dynamically generated, and should only be modified via WordPress filters.
Any changes to the directives between these markers will be overwritten.'
			),
			$marker_name
		);
		$instructions = explode( "\n", $instructions );

		foreach ( $instructions as $line => $text ) {