Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Rules::resolve and Rules::getPublicSuffix allow wider type parameters
  • Loading branch information
nyamsprod committed Mar 29, 2018
1 parent 7e42d27 commit ac9c3fa
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 38 deletions.
6 changes: 4 additions & 2 deletions README.md
Expand Up @@ -63,8 +63,8 @@ final class Rules
public static function createFromPath(string $path, $context = null): self
public static function createFromString(string $content): self
public function __construct(array $rules)
public function getPublicSuffix(string $domain = null, string $section = self::ALL_DOMAINS): PublicSuffix
public function resolve(string $domain = null, string $section = self::ALL_DOMAINS): Domain
public function getPublicSuffix($domain = null, string $section = self::ALL_DOMAINS): PublicSuffix
public function resolve($domain = null, string $section = self::ALL_DOMAINS): Domain
}
~~~

Expand Down Expand Up @@ -104,6 +104,7 @@ But also enable returns informations about the domain parts and its public suffi

final class Domain implements DomainInterface, JsonSerializable
{
public function __construct($domain = null, PublicSuffix $publicSuffix = null)
public function getPublicSuffix(): ?string
public function getRegistrableDomain(): ?string
public function getSubDomain(); ?string
Expand Down Expand Up @@ -188,6 +189,7 @@ The `Rules::getPublicSuffix` method expects the same arguments as `Rules::resolv

final class PublicSuffix implements DomainInterface, JsonSerializable
{
public function __construct($publicSuffix = null)
public function isKnown(): bool;
public function isICANN(): bool;
public function isPrivate(): bool;
Expand Down
4 changes: 1 addition & 3 deletions bin/update-psl
@@ -1,8 +1,6 @@
#!/usr/bin/env php
<?php

use Pdp;

require dirname(__DIR__).'/src/Installer.php';

Installer::updateLocalCache();
Pdp\Installer::updateLocalCache();
26 changes: 14 additions & 12 deletions src/Domain.php
Expand Up @@ -67,10 +67,10 @@ public static function __set_state(array $properties): self
/**
* New instance.
*
* @param string|null $domain
* @param mixed $domain
* @param PublicSuffix $publicSuffix
*/
public function __construct(string $domain = null, PublicSuffix $publicSuffix = null)
public function __construct($domain = null, PublicSuffix $publicSuffix = null)
{
list($this->domain, $this->labels) = $this->setDomain($domain);
$this->publicSuffix = $this->setPublicSuffix($publicSuffix ?? new PublicSuffix());
Expand Down Expand Up @@ -125,11 +125,10 @@ private function setRegistrableDomain()
return null;
}

$labels = explode('.', $this->domain);
$countLabels = count($labels);
$countPublicSuffixLabels = count($this->publicSuffix);

return implode('.', array_slice($labels, $countLabels - $countPublicSuffixLabels - 1));
return implode('.', array_slice(
explode('.', $this->domain),
count($this->labels) - count($this->publicSuffix) - 1
));
}

/**
Expand All @@ -143,14 +142,17 @@ private function setSubDomain()
return null;
}

$labels = explode('.', $this->domain);
$countLabels = count($labels);
$countLabelsToRemove = count(explode('.', $this->registrableDomain));
if ($countLabels === $countLabelsToRemove) {
$nbLabels = count($this->labels);
$nbRegistrableLabels = count($this->publicSuffix) + 1;
if ($nbLabels === $nbRegistrableLabels) {
return null;
}

return implode('.', array_slice($labels, 0, $countLabels - $countLabelsToRemove));
return implode('.', array_slice(
explode('.', $this->domain),
0,
$nbLabels - $nbRegistrableLabels
));
}

/**
Expand Down
15 changes: 13 additions & 2 deletions src/IDNAConverterTrait.php
Expand Up @@ -11,6 +11,8 @@

namespace Pdp;

use TypeError;

/**
* @internal Domain name validator
*
Expand Down Expand Up @@ -113,14 +115,18 @@ private function idnToUnicode(string $domain): string
*
* For example: setDomain('wWw.uLb.Ac.be') should return ['www.ulb.ac.be', ['be', 'ac', 'ulb', 'www']];
*
* @param string|null $domain
* @param mixed $domain
*
* @throws Exception If the domain is invalid
*
* @return array
*/
private function setDomain(string $domain = null): array
private function setDomain($domain = null): array
{
if ($domain instanceof DomainInterface) {
return [$domain->getContent(), iterator_to_array($domain, false)];
}

if (null === $domain) {
return [$domain, []];
}
Expand All @@ -129,6 +135,11 @@ private function setDomain(string $domain = null): array
return [$domain, ['']];
}

if (!is_scalar($domain) && !method_exists($domain, '__toString')) {
throw new TypeError(sprintf('The domain must be a scalar, a stringable object, a DomainInterface object or null; `%s` given', gettype($domain)));
}

$domain = (string) $domain;
if (filter_var($domain, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
throw new Exception(sprintf('The domain `%s` is invalid: this is an IPv4 host', $domain));
}
Expand Down
6 changes: 3 additions & 3 deletions src/PublicSuffix.php
Expand Up @@ -56,10 +56,10 @@ public static function __set_state(array $properties): self
/**
* New instance.
*
* @param string|null $publicSuffix
* @param string $section
* @param mixed $publicSuffix
* @param string $section
*/
public function __construct(string $publicSuffix = null, string $section = '')
public function __construct($publicSuffix = null, string $section = '')
{
list($this->publicSuffix, $this->labels) = $this->setDomain($publicSuffix);
$this->section = $this->setSection($section);
Expand Down
25 changes: 13 additions & 12 deletions src/Rules.php
Expand Up @@ -92,8 +92,8 @@ public function __construct(array $rules)
/**
* Determines the public suffix for a given domain.
*
* @param string|null $domain
* @param string $section
* @param mixed $domain
* @param string $section
*
* @throws Exception
* If the Domain is invalid or malformed
Expand All @@ -102,20 +102,21 @@ public function __construct(array $rules)
*
* @return PublicSuffix
*/
public function getPublicSuffix(string $domain = null, string $section = self::ALL_DOMAINS): PublicSuffix
public function getPublicSuffix($domain = null, string $section = self::ALL_DOMAINS): PublicSuffix
{
$this->validateSection($section);
if (!$this->isMatchable($domainObj = new Domain($domain))) {
throw new Exception(sprintf('The domain `%s` can not contain a public suffix', $domain));
$domain = $domain instanceof Domain ? $domain : new Domain($domain);
if (!$this->isMatchable($domain)) {
throw new Exception(sprintf('The domain `%s` can not contain a public suffix', $domain->getContent()));
}

$publicSuffix = $this->findPublicSuffix($domainObj, $section);
$publicSuffix = $this->findPublicSuffix($domain, $section);
if (null === $publicSuffix->getContent()) {
$publicSuffix = new PublicSuffix($domainObj->getLabel(0));
$publicSuffix = new PublicSuffix($domain->getLabel(0));
}

static $pattern = '/[^\x20-\x7f]/';
if (preg_match($pattern, $domainObj->getContent())) {
if (preg_match($pattern, $domain->getContent())) {
return $publicSuffix->toUnicode();
}

Expand All @@ -125,16 +126,16 @@ public function getPublicSuffix(string $domain = null, string $section = self::A
/**
* Returns PSL info for a given domain.
*
* @param string|null $domain
* @param string $section
* @param mixed $domain
* @param string $section
*
* @return Domain
*/
public function resolve(string $domain = null, string $section = self::ALL_DOMAINS): Domain
public function resolve($domain = null, string $section = self::ALL_DOMAINS): Domain
{
$this->validateSection($section);
try {
$domain = new Domain($domain);
$domain = $domain instanceof Domain ? $domain : new Domain($domain);
if (!$this->isMatchable($domain)) {
return $domain;
}
Expand Down
63 changes: 59 additions & 4 deletions tests/RulesTest.php
Expand Up @@ -9,8 +9,10 @@
use Pdp\Domain;
use Pdp\Exception;
use Pdp\Manager;
use Pdp\PublicSuffix;
use Pdp\Rules;
use PHPUnit\Framework\TestCase;
use TypeError;

/**
* @coversDefaultClass Pdp\Rules
Expand Down Expand Up @@ -72,13 +74,25 @@ public function testDomainInternalPhpMethod()
* @covers \Pdp\PublicSuffix::setSection
* @covers \Pdp\PublicSuffix::isKnown
* @covers \Pdp\Domain::isKnown
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testNullWillReturnNullDomain()
{
$domain = $this->rules->resolve('COM');
$this->assertFalse($domain->isKnown());
}


/**
* @covers ::resolve
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testThrowsTypeErrorOnWrongInput()
{
$this->expectException(TypeError::class);
$this->rules->resolve(date_create());
}

/**
* @covers ::resolve
* @covers ::validateSection
Expand All @@ -98,6 +112,7 @@ public function testResolveThrowsExceptionOnWrongDomainType()
* @covers \Pdp\PublicSuffix::setSection
* @covers \Pdp\PublicSuffix::isKnown
* @covers \Pdp\Domain::isKnown
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testIsSuffixValidFalse()
{
Expand All @@ -119,6 +134,7 @@ public function testIsSuffixValidFalse()
* @covers \Pdp\Domain::isKnown
* @covers \Pdp\Domain::isICANN
* @covers \Pdp\Domain::isPrivate
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testIsSuffixValidTrue()
{
Expand All @@ -142,6 +158,7 @@ public function testIsSuffixValidTrue()
* @covers \Pdp\Domain::isKnown
* @covers \Pdp\Domain::isICANN
* @covers \Pdp\Domain::isPrivate
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testIsSuffixValidFalseWithPunycoded()
{
Expand All @@ -165,6 +182,7 @@ public function testIsSuffixValidFalseWithPunycoded()
* @covers \Pdp\Domain::isKnown
* @covers \Pdp\Domain::isICANN
* @covers \Pdp\Domain::isPrivate
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testSubDomainIsNull()
{
Expand All @@ -177,7 +195,7 @@ public function testSubDomainIsNull()
/**
* @covers ::resolve
* @covers ::validateSection
* @covers \Pdp\Domain::setDomain
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testWithInvalidDomainName()
{
Expand All @@ -191,6 +209,7 @@ public function testWithInvalidDomainName()
* @covers ::findPublicSuffix
* @covers ::findPublicSuffixFromSection
* @covers \Pdp\PublicSuffix::setSection
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testWithPrivateDomain()
{
Expand All @@ -207,6 +226,7 @@ public function testWithPrivateDomain()
* @covers ::findPublicSuffix
* @covers ::findPublicSuffixFromSection
* @covers \Pdp\PublicSuffix::setSection
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testWithPrivateDomainInvalid()
{
Expand All @@ -224,6 +244,7 @@ public function testWithPrivateDomainInvalid()
* @covers ::findPublicSuffix
* @covers ::findPublicSuffixFromSection
* @covers \Pdp\PublicSuffix::setSection
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testWithPrivateDomainValid()
{
Expand All @@ -241,6 +262,7 @@ public function testWithPrivateDomainValid()
* @covers ::findPublicSuffix
* @covers ::findPublicSuffixFromSection
* @covers \Pdp\PublicSuffix::setSection
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testWithICANNDomainInvalid()
{
Expand All @@ -252,6 +274,37 @@ public function testWithICANNDomainInvalid()
$this->assertSame('ac.be', $domain->getPublicSuffix());
}

/**
* @covers ::resolve
* @covers ::validateSection
* @covers ::findPublicSuffix
* @covers ::findPublicSuffixFromSection
* @covers \Pdp\PublicSuffix::setSection
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testWithDomainObject()
{
$domain = new Domain('private.ulb.ac.be', new PublicSuffix('ac.be', Rules::ICANN_DOMAINS));
$newDomain = $this->rules->resolve($domain);
$this->assertSame('private.ulb.ac.be', $domain->getDomain());
$this->assertTrue($domain->isKnown());
$this->assertTrue($domain->isICANN());
$this->assertFalse($domain->isPrivate());
$this->assertSame('ac.be', $domain->getPublicSuffix());
$this->assertSame($domain, $newDomain);
}

/**
* @covers ::getPublicSuffix
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testWithDomainInterfaceObject()
{
$publicSuffix = new PublicSuffix('ac.be', Rules::ICANN_DOMAINS);
$psl = $this->rules->getPublicSuffix($publicSuffix);
$this->assertEquals($publicSuffix, $psl);
}

/**
* @dataProvider parseDataProvider
* @param mixed $publicSuffix
Expand All @@ -274,6 +327,7 @@ public function testGetRegistrableDomain($publicSuffix, $registrableDomain, $dom
* @param mixed $domain
* @param mixed $expectedDomain
* @covers ::resolve
* @covers \Pdp\IDNAConverterTrait::setDomain
* @covers \Pdp\Domain::setPublicSuffix
* @covers \Pdp\Domain::getPublicSuffix
*/
Expand All @@ -289,8 +343,8 @@ public function testGetPublicSuffix($publicSuffix, $registrableDomain, $domain,
* @param mixed $domain
* @param mixed $expectedDomain
* @covers ::resolve
* @covers \Pdp\IDNAConverterTrait::setDomain
* @covers \Pdp\Domain::withPublicSuffix
* @covers \Pdp\Domain::setDomain
* @covers \Pdp\Domain::getContent
*/
public function testGetDomain($publicSuffix, $registrableDomain, $domain, $expectedDomain)
Expand Down Expand Up @@ -331,8 +385,8 @@ public function parseDataProvider()
*
* @covers ::getPublicSuffix
* @covers ::validateSection
* @covers \Pdp\Domain::setDomain
* @covers ::isMatchable
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testGetPublicSuffixThrowsException($domain, $section)
{
Expand Down Expand Up @@ -360,7 +414,7 @@ public function invalidParseProvider()
* @covers ::getPublicSuffix
* @covers ::validateSection
* @covers ::isMatchable
* @covers \Pdp\PublicSuffix::setDomain
* @covers \Pdp\IDNAConverterTrait::setDomain
* @dataProvider validPublicSectionProvider
*
* @param string|null $domain
Expand Down Expand Up @@ -419,6 +473,7 @@ public function checkPublicSuffix($input, $expected)
* @covers ::findPublicSuffixFromSection
* @covers \Pdp\Domain::withPublicSuffix
* @covers \Pdp\Domain::getRegistrableDomain
* @covers \Pdp\IDNAConverterTrait::setDomain
*/
public function testPublicSuffixSpec()
{
Expand Down

0 comments on commit ac9c3fa

Please sign in to comment.