41 lines
2.3 KiB
PHP
41 lines
2.3 KiB
PHP
<?php
|
||
|
||
namespace App\Services;
|
||
|
||
use App\Support\NormalizedProjectUrl;
|
||
use InvalidArgumentException;
|
||
|
||
final class ProjectUrlNormalizer
|
||
{
|
||
public function normalize(string $input): NormalizedProjectUrl
|
||
{
|
||
$input = trim($input);
|
||
if ($input === '') throw new InvalidArgumentException('Web sitesi adresi zorunludur.');
|
||
if (! preg_match('/^[a-z][a-z0-9+.-]*:/i', $input)) $input = 'https://'.$input;
|
||
$parts = parse_url($input);
|
||
$scheme = strtolower((string) ($parts['scheme'] ?? ''));
|
||
if (! in_array($scheme, ['http', 'https'], true)) throw new InvalidArgumentException('Yalnızca http ve https adresleri kabul edilir.');
|
||
if (isset($parts['user']) || isset($parts['pass'])) throw new InvalidArgumentException('Kullanıcı bilgisi içeren adresler kabul edilmez.');
|
||
$host = strtolower(rtrim((string) ($parts['host'] ?? ''), '.'));
|
||
if ($host === '') throw new InvalidArgumentException('Geçerli bir alan adı girin.');
|
||
if (preg_match('/[^\x00-\x7f]/', $host)) {
|
||
if (! function_exists('idn_to_ascii')) throw new InvalidArgumentException('Uluslararası alan adları bu sunucuda desteklenmiyor.');
|
||
$host = idn_to_ascii($host, IDNA_DEFAULT, INTL_IDNA_VARIANT_UTS46) ?: '';
|
||
}
|
||
if (str_starts_with($host, 'www.')) $host = substr($host, 4);
|
||
if ($host === 'localhost' || str_ends_with($host, '.localhost') || filter_var($host, FILTER_VALIDATE_IP)) {
|
||
throw new InvalidArgumentException('Yerel veya IP adresleri kabul edilmez.');
|
||
}
|
||
if (strlen($host) > 253 || ! str_contains($host, '.')) throw new InvalidArgumentException('Geçerli bir alan adı girin.');
|
||
foreach (explode('.', $host) as $label) {
|
||
if ($label === '' || strlen($label) > 63 || ! preg_match('/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/', $label)) {
|
||
throw new InvalidArgumentException('Geçerli bir alan adı girin.');
|
||
}
|
||
}
|
||
$port = $parts['port'] ?? null;
|
||
if ($port !== null && ($port < 1 || $port > 65535)) throw new InvalidArgumentException('Geçerli bir port girin.');
|
||
$includePort = $port !== null && !(($scheme === 'http' && $port === 80) || ($scheme === 'https' && $port === 443));
|
||
return new NormalizedProjectUrl($host, $scheme.'://'.$host.($includePort ? ':'.$port : ''));
|
||
}
|
||
}
|