Skip to content

Commit

Permalink
Minor improvements + fix travis builds
Browse files Browse the repository at this point in the history
  • Loading branch information
bpolaszek committed Apr 23, 2019
1 parent 27bc91a commit af65a08
Show file tree
Hide file tree
Showing 16 changed files with 129 additions and 48 deletions.
8 changes: 5 additions & 3 deletions .travis.yml
Expand Up @@ -3,11 +3,13 @@ dist: xenial
language: php

php:
- 7.1
- 7.2
- '7.1'
- '7.2'
- '7.3'

before_script:
- travis_retry composer self-update
- travis_retry composer global require hirak/prestissimo
- travis_retry composer install --no-interaction --prefer-dist --dev

script:
Expand All @@ -19,4 +21,4 @@ script:
- mkdir -p build/logs && ./vendor/bin/phpunit --coverage-clover build/logs/clover.xml

after_script:
- php vendor/bin/coveralls -v
- php vendor/bin/php-coveralls -v
3 changes: 1 addition & 2 deletions README.md
Expand Up @@ -16,9 +16,8 @@ require_once __DIR__ . '/vendor/autoload.php';

use BenTools\HostnameExtractor\HostnameExtractor;
use BenTools\HostnameExtractor\SuffixProvider\PublicSuffixProvider;
use GuzzleHttp\Client;

$extractor = new HostnameExtractor(new PublicSuffixProvider(new Client()));
$extractor = new HostnameExtractor(new PublicSuffixProvider());
$hostname = $extractor->extract('my.preferred.domain.co.uk');
dump($hostname->getSubdomain()); // my.preferred
dump($hostname->getDomain()); // domain
Expand Down
8 changes: 4 additions & 4 deletions composer.json
Expand Up @@ -22,12 +22,12 @@
"require-dev": {
"bentools/uri-factory": "^1.0",
"guzzlehttp/psr7": "^1.4",
"phpunit/phpunit": "@stable",
"php-coveralls/php-coveralls": "^2.1",
"phpunit/phpunit": "^7.0",
"psr/simple-cache": "^1.0",
"satooshi/php-coveralls": "@stable",
"squizlabs/php_codesniffer": "@stable",
"squizlabs/php_codesniffer": "^3.4",
"symfony/cache": "^4.0",
"symfony/var-dumper": "^3.3"
"symfony/var-dumper": "^4.0"
},
"autoload": {
"psr-4": {
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml.dist
Expand Up @@ -15,7 +15,7 @@
stopOnFailure="false"
verbose="true"
>
<testsuite>
<testsuite name="Main">
<directory suffix="Test.php">tests</directory>
</testsuite>

Expand Down
14 changes: 5 additions & 9 deletions src/HostnameExtractor.php
Expand Up @@ -13,22 +13,18 @@

final class HostnameExtractor
{
/**
* @var SuffixProviderInterface
*/
private $suffixProvider;

/**
* @var HostnameVisitorInterface[]
*/
private $visitors = [];
private $visitors;

/**
* @inheritDoc
* HostnameExtractor constructor.
*
* @param SuffixProviderInterface|null $suffixProvider
*/
public function __construct(SuffixProviderInterface $suffixProvider)
public function __construct(SuffixProviderInterface $suffixProvider = null)
{
$this->suffixProvider = $suffixProvider;
$this->visitors = [
new IPv6Visitor(),
new Ipv4Visitor(),
Expand Down
4 changes: 2 additions & 2 deletions src/ParsedHostname.php
Expand Up @@ -56,9 +56,9 @@ public function setSubdomain(string $subdomain): void
*/
public function getSuffixedDomain(): string
{
return implode(
return \implode(
'.',
array_filter(
\array_filter(
[
$this->getDomain(),
$this->getSuffix(),
Expand Down
32 changes: 32 additions & 0 deletions src/SuffixProvider/ArraySuffixProvider.php
@@ -0,0 +1,32 @@
<?php

namespace BenTools\HostnameExtractor\SuffixProvider;

use function BenTools\Violin\string;

final class ArraySuffixProvider implements SuffixProviderInterface
{
/**
* @var array
*/
private $suffixes;

/**
* ArraySuffixProvider constructor.
*/
public function __construct(array $suffixes)
{
\usort(
$suffixes,
function ($a, $b) {
return \count(string($b)) <=> \count(string($a));
}
);
$this->suffixes = $suffixes;
}

public function getSuffixes(): iterable
{
return $this->suffixes;
}
}
17 changes: 17 additions & 0 deletions src/SuffixProvider/NaiveSuffixProvider.php
@@ -0,0 +1,17 @@
<?php

namespace BenTools\HostnameExtractor\SuffixProvider;

/**
* As this class will provide no suffix, substring after last dot may be used to determine hostname's suffix.
*/
final class NaiveSuffixProvider implements SuffixProviderInterface
{
/**
* @inheritdoc
*/
public function getSuffixes(): iterable
{
return [];
}
}
2 changes: 1 addition & 1 deletion src/SuffixProvider/PSR16CacheSuffixProvider.php
Expand Up @@ -42,7 +42,7 @@ public function __construct(
public function getSuffixes(): iterable
{
if (!$this->cache->has($this->key)) {
$suffixes = iterable_to_array($this->suffixProvider->getSuffixes());
$suffixes = \iterable_to_array($this->suffixProvider->getSuffixes());
$this->cache->set($this->key, $suffixes);
return $suffixes;
}
Expand Down
28 changes: 16 additions & 12 deletions src/SuffixProvider/PublicSuffixProvider.php
Expand Up @@ -2,6 +2,7 @@

namespace BenTools\HostnameExtractor\SuffixProvider;

use function BenTools\Violin\string;
use CallbackFilterIterator;
use GuzzleHttp\Client;

Expand All @@ -23,14 +24,17 @@ final class PublicSuffixProvider implements SuffixProviderInterface
private $cache;

/**
* @inheritDoc
* PublicSuffixProvider constructor.
*
* @param Client|null $client
* @param string $listUrl
*/
public function __construct(
Client $client,
Client $client = null,
string $listUrl = 'https://publicsuffix.org/list/public_suffix_list.dat'
) {

$this->client = $client;
$this->client = $client ?? new Client();
$this->listUrl = $listUrl;
}

Expand All @@ -43,14 +47,14 @@ public function fetchSuffixes(bool $force = false): void
$content = $this->client->get($this->listUrl)->getBody();
// Create an iterator for the document
$iterator = (function (string $content) {
$tok = strtok($content, "\r\n");
$tok = \strtok($content, "\r\n");
while (false !== $tok) {
$line = $tok;
$tok = strtok("\r\n");
$tok = \strtok("\r\n");

// Remove "*." prefixes
if (0 === strpos($line, '*.')) {
$line = substr($line, 2, mb_strlen($line) - 2);
if (0 === \strpos($line, '*.')) {
$line = \substr($line, 2, mb_strlen($line) - 2);
}

yield $line;
Expand All @@ -59,13 +63,13 @@ public function fetchSuffixes(bool $force = false): void

// Ignore commented lines
$valid = function (string $string) {
return 0 !== strpos($string, '//');
return 0 !== \strpos($string, '//');
};
$suffixes = iterator_to_array(new CallbackFilterIterator($iterator, $valid));
$suffixes = \iterator_to_array(new CallbackFilterIterator($iterator, $valid));

// Sort by suffix length
usort($suffixes, function ($a, $b) {
return mb_strlen($b) <=> mb_strlen($a);
\usort($suffixes, function (string $a, string $b) {
return \count(string($b)) <=> \count(string($a));
});

$this->cache = $suffixes;
Expand All @@ -78,6 +82,6 @@ public function fetchSuffixes(bool $force = false): void
public function getSuffixes(): iterable
{
$this->fetchSuffixes();
yield from $this->cache ?? new \EmptyIterator();
yield from ($this->cache ?? []);
}
}
8 changes: 4 additions & 4 deletions src/Visitor/DomainVisitor.php
Expand Up @@ -20,11 +20,11 @@ public function visit($hostname, ParsedHostname $parsedHostname): void
$hostname = string($hostname);
if (!$parsedHostname->isIp()) {
$suffix = $parsedHostname->getSuffix();
$withoutSuffix = null !== $suffix ? $hostname->removeRight(sprintf('.%s', $suffix)) : $hostname;
$withoutSuffix = null !== $suffix ? $hostname->removeRight(\sprintf('.%s', $suffix)) : $hostname;
if ($withoutSuffix->contains('.')) {
$domainParts = explode('.', (string) $withoutSuffix);
$parsedHostname->setDomain(array_pop($domainParts));
$parsedHostname->setSubdomain(implode('.', $domainParts));
$domainParts = \explode('.', (string) $withoutSuffix);
$parsedHostname->setDomain(\array_pop($domainParts));
$parsedHostname->setSubdomain(\implode('.', $domainParts));
} else {
$parsedHostname->setDomain((string) $withoutSuffix);
}
Expand Down
2 changes: 1 addition & 1 deletion src/Visitor/IPv6Visitor.php
Expand Up @@ -19,7 +19,7 @@ public function visit($hostname, ParsedHostname $parsedHostname): void
$hostname = string($hostname);
if ($hostname->startsWith('[') && $hostname->endsWith(']')) {
$ipv6 = (string) $hostname->removeLeft('[')->removeRight(']');
if (filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
if (\filter_var($ipv6, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) {
$parsedHostname->setIsIpv6(true);
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/Visitor/Ipv4Visitor.php
Expand Up @@ -16,7 +16,7 @@ final class Ipv4Visitor implements HostnameVisitorInterface
*/
public function visit($hostname, ParsedHostname $parsedHostname): void
{
if (false !== filter_var((string) $hostname, FILTER_VALIDATE_IP)) {
if (false !== \filter_var((string) $hostname, FILTER_VALIDATE_IP)) {
$parsedHostname->setIsIpv4(true);
}
}
Expand Down
13 changes: 7 additions & 6 deletions src/Visitor/SuffixVisitor.php
Expand Up @@ -3,9 +3,10 @@
namespace BenTools\HostnameExtractor\Visitor;

use BenTools\HostnameExtractor\ParsedHostname;
use BenTools\HostnameExtractor\SuffixProvider\NaiveSuffixProvider;
use BenTools\HostnameExtractor\SuffixProvider\SuffixProviderInterface;
use function BenTools\Violin\string;
use BenTools\Violin\Violin;
use function BenTools\Violin\string;

/**
* Class SuffixVisitor
Expand All @@ -21,9 +22,9 @@ final class SuffixVisitor implements HostnameVisitorInterface
/**
* @inheritDoc
*/
public function __construct(SuffixProviderInterface $suffixProvider)
public function __construct(SuffixProviderInterface $suffixProvider = null)
{
$this->suffixProvider = $suffixProvider;
$this->suffixProvider = $suffixProvider ?? new NaiveSuffixProvider();
}

/**
Expand All @@ -37,8 +38,8 @@ public function visit($hostname, ParsedHostname $parsedHostname): void
if (null !== $suffix) {
$parsedHostname->setSuffix($suffix);
} else {
$hostnameParts = explode('.', $hostname);
$parsedHostname->setSuffix(array_pop($hostnameParts));
$hostnameParts = \explode('.', $hostname);
$parsedHostname->setSuffix(\array_pop($hostnameParts));
}
}
}
Expand All @@ -50,7 +51,7 @@ public function visit($hostname, ParsedHostname $parsedHostname): void
private function findSuffix(Violin $hostname): ?string
{
foreach ($this->suffixProvider->getSuffixes() as $suffix) {
if ($hostname->endsWith(sprintf('.%s', $suffix))) {
if ($hostname->endsWith(\sprintf('.%s', $suffix))) {
return $suffix;
}
}
Expand Down
4 changes: 2 additions & 2 deletions src/Visitor/TldVisitor.php
Expand Up @@ -20,8 +20,8 @@ public function visit($hostname, ParsedHostname $parsedHostname): void
if (null !== $parsedHostname->getSuffix()) {
$suffix = string($parsedHostname->getSuffix());
if ($suffix->contains('.')) {
$suffixParts = explode('.', (string) $suffix);
$parsedHostname->setTld(array_pop($suffixParts));
$suffixParts = \explode('.', (string) $suffix);
$parsedHostname->setTld(\array_pop($suffixParts));
} else {
$parsedHostname->setTld((string) $suffix);
}
Expand Down
30 changes: 30 additions & 0 deletions tests/ArraySuffixProviderTest.php
@@ -0,0 +1,30 @@
<?php

namespace BenTools\HostnameExtractor\Tests;

use BenTools\HostnameExtractor\SuffixProvider\ArraySuffixProvider;
use PHPUnit\Framework\TestCase;

class ArraySuffixProviderTest extends TestCase
{
/**
* @test
*/
public function it_provides_suffixes_in_the_correct_order()
{
$suffixes = [
'.com',
'.co.uk',
'.au',
];

$provider = new ArraySuffixProvider($suffixes);
$expected = [
'.co.uk',
'.com',
'.au',
];

$this->assertSame($expected, $provider->getSuffixes());
}
}

0 comments on commit af65a08

Please sign in to comment.