File: //proc/self/cwd/wp-content/plugins/plugin-check/includes/Traits/URL_Utils.php
<?php
/**
* Trait WordPress\Plugin_Check\Traits\URL_Utils
*
* @package plugin-check
*/
namespace WordPress\Plugin_Check\Traits;
/**
* Trait for URL utilities.
*
* @since 1.6.0
*/
trait URL_Utils {
/**
* Checks if URL is valid.
*
* @since 1.6.0
*
* @param string $url URL.
* @return bool true if the URL is valid, otherwise false.
*/
protected function is_valid_url( string $url ): bool {
// Must start with http or https.
if ( ! str_starts_with( $url, 'http' ) ) {
return false;
}
// Parse the URL to validate its structure.
$parsed_url = wp_parse_url( $url );
// wp_parse_url returns false on parse failure.
if ( false === $parsed_url || ! is_array( $parsed_url ) ) {
return false;
}
// Must have a valid scheme and host.
if ( empty( $parsed_url['scheme'] ) || empty( $parsed_url['host'] ) ) {
return false;
}
// Validate host doesn't contain obviously invalid characters.
// Allow alphanumeric, dots, hyphens, and underscores (for localhost, etc.).
if ( preg_match( '/[^a-z0-9.\-_]/i', $parsed_url['host'] ) ) {
return false;
}
// Detect duplicated protocol in the host/path portion (e.g., "https://http://example.com/").
// Only check up to the query string to avoid false positives with URLs in query parameters.
$query_position = strpos( $url, '?' );
if ( false !== $query_position ) {
$url_without_query = substr( $url, 0, $query_position );
} else {
$url_without_query = $url;
}
// Check for duplicated protocol after the scheme:// portion.
$scheme_length = strlen( $parsed_url['scheme'] );
$after_scheme = substr( $url_without_query, $scheme_length + 3 );
if ( str_contains( $after_scheme, '://' ) ) {
return false;
}
return true;
}
/**
* Finds and returns the discouraged domain matched in the URL's host, or null if none.
*
* @since 1.6.0
*
* @param string $url The URL to check.
* @return string|null The matched discouraged domain, or null if none matched.
*/
protected function find_discouraged_domain( string $url ) {
$discouraged_domains = $this->get_discouraged_domains();
if ( empty( $discouraged_domains ) ) {
return null;
}
$parsed_url = wp_parse_url( $url );
if ( empty( $parsed_url['host'] ) ) {
return null;
}
$host = strtolower( rtrim( $parsed_url['host'], '.' ) );
foreach ( $discouraged_domains as $domain ) {
$domain = strtolower( rtrim( $domain, '.' ) );
if (
$host === $domain ||
( strlen( $host ) > strlen( $domain ) && substr( $host, -strlen( $domain ) - 1 ) === '.' . $domain )
) {
return $domain;
}
}
return null;
}
/**
* Checks if URL has discouraged domain.
*
* @since 1.6.0
*
* @param string $url The URL to check.
* @return bool True if the URL has a discouraged domain, false otherwise.
*/
protected function has_discouraged_domain( $url ) {
return null !== $this->find_discouraged_domain( $url );
}
/**
* Returns discouraged domains.
*
* @since 1.6.0
*
* @return array Discouraged domains.
*/
private function get_discouraged_domains() {
$discouraged_domains = array(
'example.com',
'example.net',
'example.org',
'yourdomain.com',
'yourwebsite.com',
);
/**
* Filter the list of discouraged domains.
*
* @since 1.6.0
*
* @param array $discouraged_domains Array of discouraged domains.
*/
$discouraged_domains = (array) apply_filters( 'wp_plugin_check_discouraged_domains', $discouraged_domains );
return $discouraged_domains;
}
}