Skip to content

Commit 99a63b8

Browse files
committed
Improve PHP domain classes implementation
1 parent b54a313 commit 99a63b8

14 files changed

+61
-57
lines changed

composer.json

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -48,11 +48,11 @@
4848
"require-dev": {
4949
"friendsofphp/php-cs-fixer": "^v3.8.0",
5050
"guzzlehttp/guzzle": "^7.5",
51-
"guzzlehttp/psr7": "^1.6 || ^2.4.1",
52-
"phpstan/phpstan": "^1.8.6",
53-
"phpstan/phpstan-phpunit": "^1.1.1",
51+
"guzzlehttp/psr7": "^1.6 || ^2.4.3",
52+
"phpstan/phpstan": "^1.9",
53+
"phpstan/phpstan-phpunit": "^1.2.2",
5454
"phpstan/phpstan-strict-rules": "^1.4.4",
55-
"phpunit/phpunit": "^9.5.25",
55+
"phpunit/phpunit": "^9.5.26",
5656
"psr/http-factory": "^1.0.1",
5757
"psr/simple-cache": "^1.0.1",
5858
"symfony/cache": "^v5.0.0 || ^v6.0.0"

src/Domain.php

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@ final class Domain implements DomainName
3939
private const REGEXP_URI_DELIMITERS = '/[:\/?#\[\]@ ]/';
4040

4141
/** @var array<int, string> */
42-
private array $labels;
43-
private ?string $domain;
42+
private readonly array $labels;
43+
private readonly ?string $domain;
4444

4545
private function __construct(private string $type, DomainNameProvider|Host|Stringable|string|int|null $domain)
4646
{
@@ -315,11 +315,11 @@ public function withoutLabel(int $key, int ...$keys): self
315315
}
316316
}
317317

318-
$clone = clone $this;
319-
$clone->labels = $labels;
320-
$clone->domain = [] === $labels ? null : implode('.', array_reverse($labels));
318+
if ($labels === $this->labels) {
319+
return $this;
320+
}
321321

322-
return $clone;
322+
return new self($this->type, [] === $labels ? null : implode('.', array_reverse($labels)));
323323
}
324324

325325
public function clear(): self
@@ -343,10 +343,6 @@ public function slice(int $offset, int $length = null): self
343343
return $this;
344344
}
345345

346-
$clone = clone $this;
347-
$clone->labels = $labels;
348-
$clone->domain = [] === $labels ? null : implode('.', array_reverse($labels));
349-
350-
return $clone;
346+
return new self($this->type, [] === $labels ? null : implode('.', array_reverse($labels)));
351347
}
352348
}

src/ResolvedDomain.php

Lines changed: 25 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,19 @@
99

1010
final class ResolvedDomain implements ResolvedDomainName
1111
{
12-
private DomainName $secondLevelDomain;
13-
private DomainName $registrableDomain;
14-
private DomainName $subDomain;
12+
private readonly DomainName $secondLevelDomain;
13+
private readonly DomainName $registrableDomain;
14+
private readonly DomainName $subDomain;
1515

1616
private function __construct(
17-
private DomainName $domain,
18-
private EffectiveTopLevelDomain $suffix
17+
private readonly DomainName $domain,
18+
private readonly EffectiveTopLevelDomain $suffix
1919
) {
20-
$this->validateState();
20+
[
21+
'registrableDomain' => $this->registrableDomain,
22+
'secondLevelDomain' => $this->secondLevelDomain,
23+
'subDomain' => $this->subDomain,
24+
] = $this->parse();
2125
}
2226

2327
public static function fromICANN(int|DomainNameProvider|Host|string|Stringable|null $domain, int $suffixLength): self
@@ -69,16 +73,20 @@ private static function setDomainName(int|DomainNameProvider|Host|string|Stringa
6973
* Make sure the Value Object is always in a valid state.
7074
*
7175
* @throws UnableToResolveDomain If the suffix can not be attached to the domain
76+
*
77+
* @return array{registrableDomain: DomainName, secondLevelDomain: DomainName, subDomain: DomainName}
7278
*/
73-
private function validateState(): void
79+
private function parse(): array
7480
{
7581
$suffixValue = $this->suffix->value();
7682
if (null === $suffixValue) {
7783
$nullDomain = $this->domain->clear();
78-
$this->registrableDomain = $nullDomain;
79-
$this->secondLevelDomain = $nullDomain;
80-
$this->subDomain = $nullDomain;
81-
return;
84+
85+
return [
86+
'registrableDomain' => $nullDomain,
87+
'secondLevelDomain' => $nullDomain,
88+
'subDomain' => $nullDomain,
89+
];
8290
}
8391

8492
if (2 > count($this->domain)) {
@@ -90,9 +98,12 @@ private function validateState(): void
9098
}
9199

92100
$length = count($this->suffix);
93-
$this->registrableDomain = $this->domain->slice(0, $length + 1);
94-
$this->secondLevelDomain = $this->domain->slice($length, 1);
95-
$this->subDomain = $this->domain->slice($length + 1);
101+
102+
return [
103+
'registrableDomain' => $this->domain->slice(0, $length + 1),
104+
'secondLevelDomain' => $this->domain->slice($length, 1),
105+
'subDomain' => $this->domain->slice($length + 1),
106+
];
96107
}
97108

98109
public function count(): int

src/Rules.php

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -275,10 +275,8 @@ private function getPublicSuffixLengthFromSection(DomainName $domain, string $se
275275

276276
//no match found
277277
if (!array_key_exists($label, $rules)) {
278-
// for private domain suffix MUST be fully matched else no suffix is found
279-
// https://github.com/jeremykendall/php-domain-parser/issues/321
280-
// https://github.com/jeremykendall/php-domain-parser/issues/334
281-
if (self::PRIVATE_DOMAINS === $section && self::hasRemainingRuleLabels($rules)) {
278+
// Suffix MUST be fully matched else no suffix is found for private domain
279+
if (self::PRIVATE_DOMAINS === $section && self::hasRemainingRules($rules)) {
282280
$labelCount = 0;
283281
}
284282
break;
@@ -292,7 +290,7 @@ private function getPublicSuffixLengthFromSection(DomainName $domain, string $se
292290
return $labelCount;
293291
}
294292

295-
private static function hasRemainingRuleLabels(array $rules): bool
293+
private static function hasRemainingRules(array $rules): bool
296294
{
297295
foreach ($rules as $rule) {
298296
if ([] !== $rule) {

src/Storage/PsrStorageFactory.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ final class PsrStorageFactory implements
1818
TopLevelDomainListStorageFactory
1919
{
2020
public function __construct(
21-
private CacheInterface $cache,
22-
private ClientInterface $client,
23-
private RequestFactoryInterface $requestFactory
21+
private readonly CacheInterface $cache,
22+
private readonly ClientInterface $client,
23+
private readonly RequestFactoryInterface $requestFactory
2424
) {
2525
}
2626

src/Storage/PublicSuffixListPsr16Cache.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
final class PublicSuffixListPsr16Cache implements PublicSuffixListCache
1818
{
19-
private ?DateInterval $cacheTtl;
19+
private readonly ?DateInterval $cacheTtl;
2020

2121
public function __construct(
22-
private CacheInterface $cache,
23-
private string $cachePrefix = '',
22+
private readonly CacheInterface $cache,
23+
private readonly string $cachePrefix = '',
2424
DateInterval|DateTimeInterface|Stringable|int|string|null $cacheTtl = null
2525
) {
2626
$this->cacheTtl = TimeToLive::convert($cacheTtl);

src/Storage/PublicSuffixListPsr18Client.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
final class PublicSuffixListPsr18Client implements PublicSuffixListClient
1515
{
1616
public function __construct(
17-
private ClientInterface $client,
18-
private RequestFactoryInterface $requestFactory
17+
private readonly ClientInterface $client,
18+
private readonly RequestFactoryInterface $requestFactory
1919
) {
2020
}
2121

src/Storage/RulesStorage.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@
99
final class RulesStorage implements PublicSuffixListStorage
1010
{
1111
public function __construct(
12-
private PublicSuffixListCache $cache,
13-
private PublicSuffixListClient $client
12+
private readonly PublicSuffixListCache $cache,
13+
private readonly PublicSuffixListClient $client
1414
) {
1515
}
1616

src/Storage/TopLevelDomainListPsr16Cache.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,11 @@
1616

1717
final class TopLevelDomainListPsr16Cache implements TopLevelDomainListCache
1818
{
19-
private ?DateInterval $cacheTtl;
19+
private readonly ?DateInterval $cacheTtl;
2020

2121
public function __construct(
22-
private CacheInterface $cache,
23-
private string $cachePrefix = '',
22+
private readonly CacheInterface $cache,
23+
private readonly string $cachePrefix = '',
2424
DateInterval|DateTimeInterface|Stringable|int|string|null $cacheTtl = null
2525
) {
2626
$this->cacheTtl = TimeToLive::convert($cacheTtl);

src/Storage/TopLevelDomainListPsr18Client.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@
1414
final class TopLevelDomainListPsr18Client implements TopLevelDomainListClient
1515
{
1616
public function __construct(
17-
private ClientInterface $client,
18-
private RequestFactoryInterface $requestFactory
17+
private readonly ClientInterface $client,
18+
private readonly RequestFactoryInterface $requestFactory
1919
) {
2020
}
2121

0 commit comments

Comments
 (0)