Skip to content
wiki.fftac.org

Path

**Site relevance:** Antichrist.net

**Memory type:** plugin source memory

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

**Size:** 8.5 KB

Summary

namespace UAIXLocaleRouter\Support;

Source Preview

This source file is short enough to preview directly on its source-memory page.

<?php

namespace UAIXLocaleRouter\Support;

use UAIXLocaleRouter\LocaleRepository;
use UAIXLocaleRouter\Plugin;


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

final class Path {
	/**
	 * Current request path.
	 *
	 * @return string
	 */
	public static function request_path() {
		$request_uri = isset( $_SERVER['REQUEST_URI'] ) ? (string) wp_unslash( $_SERVER['REQUEST_URI'] ) : '/';
		$path        = wp_parse_url( $request_uri, PHP_URL_PATH );

		return is_string( $path ) && '' !== $path ? $path : '/';
	}

	/**
	 * Current request query args.
	 *
	 * @return array
	 */
	public static function current_query_args() {
		if ( empty( $_SERVER['QUERY_STRING'] ) ) {
			return array();
		}

		parse_str( (string) wp_unslash( $_SERVER['QUERY_STRING'] ), $query );

		return is_array( $query ) ? $query : array();
	}

	/**
	 * Normalize a path with a leading slash.
	 *
	 * @param string $path Path input.
	 * @return string
	 */
	public static function normalize_path( $path ) {
		$path = trim( (string) $path );

		if ( '' === $path ) {
			return '/';
		}

		$parsed = false !== strpos( $path, '://' ) || false !== strpos( $path, '?' ) || false !== strpos( $path, '#' )
			? wp_parse_url( $path, PHP_URL_PATH )
			: $path;

		$path = is_string( $parsed ) && '' !== $parsed ? $parsed : '/';
		$path = preg_replace( '/[\x00-\x1F\x7F]/', '', $path );
		$path = str_replace( '\\', '/', (string) $path );
		$path = '/' . ltrim( $path, '/' );
		$path = preg_replace( '#/+#', '/', $path );

		return is_string( $path ) && '' !== $path ? $path : '/';
	}

	/**
	 * Return path segments.
	 *
	 * @param string $path Path input.
	 * @return array
	 */
	public static function segments( $path ) {
		return array_values(
			array_filter(
				explode( '/', trim( self::normalize_path( $path ), '/' ) ),
				'strlen'
			)
		);
	}

	/**
	 * Determine whether the path points at a static asset.
	 *
	 * @param string $path Path input.
	 * @return bool
	 */
	public static function is_static_asset_path( $path ) {
		return (bool) preg_match( '#\.(?:css|js|map|png|jpg|jpeg|gif|svg|webp|ico|woff2?|ttf|eot|pdf|txt|xml)$#i', (string) $path );
	}

	/**
	 * Remove an enabled locale prefix from a path.
	 *
	 * @param string $path Path input.
	 * @return string
	 */
	public static function strip_locale_prefix( $path ) {
		$segments = self::segments( $path );

		if ( ! empty( $segments ) && LocaleRepository::is_enabled_url_tag( LocaleRepository::normalize_url_tag( $segments[0] ) ) ) {
			array_shift( $segments );
		}

		return self::join_segments( $segments );
	}

	/**
	 * Join path segments into a normalized path.
	 *
	 * @param array $segments Path segments.
	 * @return string
	 */
	public static function join_segments( array $segments ) {
		$segments = array_values( array_filter( $segments, 'strlen' ) );

		return empty( $segments ) ? '/' : '/' . implode( '/', $segments ) . '/';
	}

	/**
	 * Build a front-end absolute URL without using filtered home_url().
	 *
	 * @param string $path Path component.
	 * @param array  $query Query arguments.
	 * @param string $fragment Fragment.
	 * @return string
	 */
	public static function build_front_url( $path = '/', array $query = array(), $fragment = '' ) {
		$base = self::site_base_url();
		$path = self::normalize_localized_path( $path );
		$url  = $base . $path;

		if ( ! empty( $query ) ) {
			$url = add_query_arg( $query, $url );
		}

		if ( '' !== $fragment ) {
			$url .= '#' . ltrim( (string) $fragment, '#' );
		}

		return $url;
	}

	/**
	 * Return the normalized front-end base URL while preserving the active request scheme when possible.
	 *
	 * @return string
	 */
	public static function site_base_url() {
		$home  = (string) get_option( 'home' );
		$parts = wp_parse_url( $home );

		if ( ! is_array( $parts ) || empty( $parts['host'] ) ) {
			return untrailingslashit( $home );
		}

		$scheme = self::preferred_front_scheme( isset( $parts['scheme'] ) ? (string) $parts['scheme'] : 'http' );
		$auth   = '';
		$path   = isset( $parts['path'] ) ? untrailingslashit( (string) $parts['path'] ) : '';
		$port   = isset( $parts['port'] ) ? ':' . absint( $parts['port'] ) : '';

		if ( ! empty( $parts['user'] ) ) {
			$auth = (string) $parts['user'];

			if ( isset( $parts['pass'] ) ) {
				$auth .= ':' . (string) $parts['pass'];
			}

			$auth .= '@';
		}

		return $scheme . '://' . $auth . $parts['host'] . $port . $path;
	}

	/**
	 * Determine the best front-end scheme for generated URLs.
	 *
	 * @param string $fallback_scheme Fallback scheme.
	 * @return string
	 */
	public static function preferred_front_scheme( $fallback_scheme = 'http' ) {
		$detected_scheme = self::detect_request_scheme();

		if ( '' !== $detected_scheme ) {
			return $detected_scheme;
		}

		$fallback_scheme = strtolower( (string) $fallback_scheme );

		return in_array( $fallback_scheme, array( 'http', 'https' ), true ) ? $fallback_scheme : 'http';
	}

	/**
	 * Detect the current request scheme, including common reverse-proxy headers.
	 *
	 * @return string
	 */
	public static function detect_request_scheme() {
		if ( function_exists( 'is_ssl' ) && is_ssl() ) {
			return 'https';
		}

		$https = isset( $_SERVER['HTTPS'] ) ? strtolower( (string) wp_unslash( $_SERVER['HTTPS'] ) ) : '';

		if ( 'on' === $https || '1' === $https ) {
			return 'https';
		}

		$forwarded_proto = '';

		if ( isset( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) ) {
			$forwarded_values = explode( ',', (string) wp_unslash( $_SERVER['HTTP_X_FORWARDED_PROTO'] ) );
			$forwarded_proto  = strtolower( trim( (string) reset( $forwarded_values ) ) );
		}

		if ( 'https' === $forwarded_proto || 'http' === $forwarded_proto ) {
			return $forwarded_proto;
		}

		$forwarded_ssl = isset( $_SERVER['HTTP_X_FORWARDED_SSL'] ) ? strtolower( (string) wp_unslash( $_SERVER['HTTP_X_FORWARDED_SSL'] ) ) : '';

		if ( 'on' === $forwarded_ssl || '1' === $forwarded_ssl ) {
			return 'https';
		}

		$cf_visitor = isset( $_SERVER['HTTP_CF_VISITOR'] ) ? (string) wp_unslash( $_SERVER['HTTP_CF_VISITOR'] ) : '';

		if ( '' !== $cf_visitor ) {
			$data = json_decode( $cf_visitor, true );

			if ( is_array( $data ) && ! empty( $data['scheme'] ) ) {
				$scheme = strtolower( (string) $data['scheme'] );

				if ( 'https' === $scheme || 'http' === $scheme ) {
					return $scheme;
				}
			}
		}

		$request_scheme = isset( $_SERVER['REQUEST_SCHEME'] ) ? strtolower( (string) wp_unslash( $_SERVER['REQUEST_SCHEME'] ) ) : '';

		if ( 'https' === $request_scheme || 'http' === $request_scheme ) {
			return $request_scheme;
		}

		$server_port = isset( $_SERVER['SERVER_PORT'] ) ? (string) wp_unslash( $_SERVER['SERVER_PORT'] ) : '';

		if ( '443' === $server_port ) {
			return 'https';
		}

		if ( '80' === $server_port ) {
			return 'http';
		}

		return '';
	}

	/**
	 * Return a normalized localized path respecting slash settings.
	 *
	 * @param string $path Path input.
	 * @return string
	 */
	public static function normalize_localized_path( $path ) {
		$path     = self::normalize_path( $path );
		$settings = Plugin::settings();

		if ( '/' === $path ) {
			return '/';
		}

		if ( self::is_static_asset_path( $path ) ) {
			return $path;
		}

		if ( 'never' === $settings['trailing_slash_strategy'] ) {
			return untrailingslashit( $path );
		}

		if ( 'always' === $settings['trailing_slash_strategy'] ) {
			return trailingslashit( $path );
		}

		return $path;
	}

	/**
	 * Apply a locale prefix to a path.
	 *
	 * @param string $path Path input.
	 * @param string $url_tag Locale URL tag.
	 * @return string
	 */
	public static function localize_path( $path, $url_tag ) {
		$path = self::normalize_path( $path );

		if ( self::is_static_asset_path( $path ) ) {
			return $path;
		}

		$segments = self::segments( self::strip_locale_prefix( $path ) );
		array_unshift( $segments, LocaleRepository::normalize_url_tag( $url_tag ) );

		return self::normalize_localized_path( self::join_segments( $segments ) );
	}

	/**
	 * Determine whether the URL points outside the site.
	 *
	 * @param string $url URL input.
	 * @return bool
	 */
	public static function is_external_url( $url ) {
		if ( '' === $url || 0 === strpos( $url, '/' ) ) {
			return false;
		}

		$host      = wp_parse_url( $url, PHP_URL_HOST );
		$site_host = wp_parse_url( (string) get_option( 'home' ), PHP_URL_HOST );

		return is_string( $host ) && is_string( $site_host ) && strtolower( $host ) !== strtolower( $site_host );
	}
}