Skip to content

Commit 62a89a4

Browse files
committed
adding domain modifiers functions
1 parent c79cf7f commit 62a89a4

File tree

7 files changed

+728
-1
lines changed

7 files changed

+728
-1
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,17 @@ All Notable changes to `PHP Domain Parser` **5.x** series will be documented in
1010
- `Pdp\Domain::getContent` returns the Domain name value replaces `Pdp\Domain::getDomain`
1111
- `Pdp\Domain` implements the `Countable` interface.
1212
- `Pdp\Domain::withPublicSuffix` returns a new Domain object with a different Public Suffix
13+
- `Pdp\PublicSuffix::createFromDomain` returns a new `Pdp\PublicSuffix` object from a `Pdp\Domain`object
14+
- `Pdp\append` append a host to a domain name
15+
- `Pdp\prepend` prepend a host to a domain name
16+
- `Pdp\replace` replace a label from the domain name
17+
- `Pdp\public_suffix_replace` replace the domain name public suffix
1318

1419
### Fixed
1520

1621
- `Pdp\Domain` domain part computation (public suffix, registrable domain and sub domain)
1722
- `Pdp\Domain` and `Pdp\PublicSuffix` host validation compliance to RFC improved
23+
- Improved `Pdp\Converter` and `Pdp\Manager` class to better report error on IDN conversion.
1824

1925
### Deprecated
2026

composer.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,8 @@
5555
"autoload": {
5656
"psr-4": {
5757
"Pdp\\": "src/"
58-
}
58+
},
59+
"files": ["src/functions_include.php"]
5960
},
6061
"autoload-dev": {
6162
"psr-4": {

phpunit.xml.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
<directory suffix=".php">src</directory>
2323
<exclude>
2424
<directory suffix="Installer.php">src</directory>
25+
<directory suffix="include.php">src</directory>
2526
</exclude>
2627
<exclude>src/Installer</exclude>
2728
</whitelist>

src/PublicSuffix.php

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,26 @@ public static function __set_state(array $properties): self
5353
return new self($properties['publicSuffix'], $properties['section']);
5454
}
5555

56+
/**
57+
* Create an new instance from a Domain object
58+
*
59+
* @param Domain $domain
60+
*
61+
* @return self
62+
*/
63+
public static function createFromDomain(Domain $domain): self
64+
{
65+
if (!$domain->isKnown()) {
66+
return new self($domain->getPublicSuffix());
67+
}
68+
69+
if ($domain->isICANN()) {
70+
return new self($domain->getPublicSuffix(), Rules::ICANN_DOMAINS);
71+
}
72+
73+
return new self($domain->getPublicSuffix(), Rules::PRIVATE_DOMAINS);
74+
}
75+
5676
/**
5777
* New instance.
5878
*

src/functions.php

Lines changed: 183 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
<?php
2+
/**
3+
* PHP Domain Parser: Public Suffix List based URL parsing.
4+
*
5+
* @see http://github.com/jeremykendall/php-domain-parser for the canonical source repository
6+
*
7+
* @copyright Copyright (c) 2017 Jeremy Kendall (http://jeremykendall.net)
8+
* @license http://github.com/jeremykendall/php-domain-parser/blob/master/LICENSE MIT License
9+
*/
10+
declare(strict_types=1);
11+
12+
namespace Pdp;
13+
14+
/**
15+
* Append a domain name to another domain name.
16+
*
17+
* @param mixed $host
18+
* @param mixed $subject
19+
*
20+
* @return Domain
21+
*/
22+
function append($host, $subject): Domain
23+
{
24+
if (!$subject instanceof Domain) {
25+
$subject = new Domain($subject);
26+
}
27+
28+
if (!$host instanceof DomainInterface) {
29+
$host = new Domain($host);
30+
}
31+
32+
if (null === $host->getContent()) {
33+
return $subject;
34+
}
35+
36+
static $pattern = '/[^\x20-\x7f]/';
37+
$dContent = $subject->getContent();
38+
$host = preg_match($pattern, $dContent) ? $host->toUnicode() : $host->toAscii();
39+
$domain = new Domain($dContent.'.'.$host->getContent());
40+
41+
if ($host instanceof PublicSuffix) {
42+
return $domain->withPublicSuffix($host);
43+
}
44+
45+
if ($host instanceof Domain) {
46+
return $domain->withPublicSuffix(PublicSuffix::createFromDomain($host));
47+
}
48+
49+
return $domain;
50+
}
51+
52+
/**
53+
* Prepend a domain name to another domain name.
54+
*
55+
* @param mixed $host
56+
* @param mixed $subject
57+
*
58+
* @return Domain
59+
*/
60+
function prepend($host, $subject): Domain
61+
{
62+
if (!$subject instanceof Domain) {
63+
$subject = new Domain($subject);
64+
}
65+
66+
if (!$host instanceof DomainInterface) {
67+
$host = new PublicSuffix($host);
68+
}
69+
70+
if (null === $host->getContent()) {
71+
return $subject;
72+
}
73+
74+
$dContent = $subject->getContent();
75+
static $pattern = '/[^\x20-\x7f]/';
76+
$host = preg_match($pattern, $dContent) ? $host->toUnicode() : $host->toAscii();
77+
78+
return new Domain($host->getContent().'.'.$dContent, PublicSuffix::createFromDomain($subject));
79+
}
80+
81+
/**
82+
* Replace a label from the domain with a domain name
83+
*
84+
* @param int $key
85+
* @param mixed $label
86+
* @param mixed $subject
87+
*
88+
* @return Domain
89+
*/
90+
function replace(int $key, $label, $subject): Domain
91+
{
92+
if (!$subject instanceof Domain) {
93+
$subject = new Domain($subject);
94+
}
95+
96+
if (!$label instanceof DomainInterface) {
97+
$label = new Domain($label);
98+
}
99+
100+
if (null === $label->getContent()) {
101+
return $subject;
102+
}
103+
104+
$nb_labels = count($subject);
105+
$offset = filter_var($key, FILTER_VALIDATE_INT, ['options' => ['min_range' => - $nb_labels, 'max_range' => $nb_labels - 1]]);
106+
if (false === $offset) {
107+
throw new Exception(sprintf('no label was found for the given key `%s`', $key));
108+
}
109+
110+
if ($offset < 0) {
111+
$offset = $nb_labels + $offset;
112+
}
113+
114+
static $pattern = '/[^\x20-\x7f]/';
115+
$label = preg_match($pattern, $subject->getContent()) ? $label->toUnicode() : $label->toAscii();
116+
if ($label->getContent() === $subject->getLabel($offset)) {
117+
return $subject;
118+
}
119+
120+
$labels = iterator_to_array($subject, false);
121+
$labels[$offset] = $label->getContent();
122+
$domain = new Domain(implode('.', array_reverse($labels)));
123+
124+
$subjectPS = PublicSuffix::createFromDomain($subject);
125+
if ($key >= count($subjectPS)) {
126+
return $domain->withPublicSuffix($subjectPS);
127+
}
128+
129+
if ($key !== 0) {
130+
return $domain;
131+
}
132+
133+
if ($label instanceof PublicSuffix) {
134+
return $domain->withPublicSuffix($label);
135+
}
136+
137+
if ($label instanceof Domain) {
138+
return $domain->withPublicSuffix(PublicSuffix::createFromDomain($label));
139+
}
140+
141+
return $domain->withPublicSuffix(new PublicSuffix($label->getContent()));
142+
}
143+
144+
/**
145+
* Replace the public suffix for a given Domain name.
146+
*
147+
* If the domain has no information regarding its public suffix
148+
* its last label will be considered as its public suffix label and will
149+
* be replaced.
150+
*
151+
* @param mixed $publicSuffix
152+
* @param mixed $subject
153+
*
154+
* @return Domain
155+
*/
156+
function public_suffix_replace($publicSuffix, $subject): Domain
157+
{
158+
if (!$subject instanceof Domain) {
159+
$subject = new Domain($subject);
160+
$subject = $subject->withPublicSuffix(new PublicSuffix($subject->getLabel(0)));
161+
}
162+
163+
if (!$publicSuffix instanceof PublicSuffix) {
164+
$publicSuffix = new PublicSuffix($publicSuffix);
165+
}
166+
167+
if (null === $publicSuffix->getContent()) {
168+
return $subject->withPublicSuffix($publicSuffix);
169+
}
170+
171+
$dContent = $subject->getContent();
172+
$dPublicSuffix = $subject->getPublicSuffix();
173+
174+
static $pattern = '/[^\x20-\x7f]/';
175+
$publicSuffix = preg_match($pattern, $dContent) ? $publicSuffix->toUnicode() : $publicSuffix->toAscii();
176+
177+
$psContent = $publicSuffix->getContent();
178+
if ($dPublicSuffix === $psContent) {
179+
return $subject;
180+
}
181+
182+
return new Domain(substr($dContent, 0, - strlen($dPublicSuffix)).$psContent, $publicSuffix);
183+
}

src/functions_include.php

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
<?php
2+
3+
// Don't redefine the functions if included multiple times.
4+
if (!function_exists('Pdp\append')) {
5+
require __DIR__.'/functions.php';
6+
}

0 commit comments

Comments
 (0)