Completed
Push — master ( c07126...706ec6 )
by Jan-Petter
04:09
created

HostClient::isUriListed()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 22
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 2 Features 1
Metric Value
c 2
b 2
f 1
dl 0
loc 22
rs 8.9197
cc 4
eloc 16
nc 6
nop 1
1
<?php
2
namespace vipnytt\RobotsTxtParser\Client\Directives;
3
4
use vipnytt\RobotsTxtParser\Parser\UriParser;
5
6
/**
7
 * Class HostClient
8
 *
9
 * @see https://github.com/VIPnytt/RobotsTxtParser/blob/master/docs/methods/HostClient.md for documentation
10
 * @package vipnytt\RobotsTxtParser\Client\Directives
11
 */
12
class HostClient implements ClientInterface
13
{
14
    /**
15
     * Base uri
16
     * @var string
17
     */
18
    private $base;
19
20
    /**
21
     * Effective uri
22
     * @var string
23
     */
24
    private $effective;
25
26
    /**
27
     * Host values
28
     * @var string[]
29
     */
30
    private $host;
31
32
    /**
33
     * Parent directive
34
     * @var string|null
35
     */
36
    private $parent;
37
38
    /**
39
     * HostClient constructor.
40
     *
41
     * @param string $base
42
     * @param string $effective
43
     * @param string[] $host
44
     * @param string|null $parentDirective
45
     */
46
    public function __construct($base, $effective, array $host, $parentDirective = null)
47
    {
48
        $this->base = $base;
49
        $this->effective = $effective;
50
        $this->host = $host;
51
        $this->parent = $parentDirective;
52
    }
53
54
    /**
55
     * Is preferred host
56
     *
57
     * @return bool
58
     */
59
    public function isPreferred()
60
    {
61
        if (($host = $this->get()) === null) {
62
            return $this->base === $this->effective;
63
        }
64
        $parsed = parse_url($host);
65
        $new = [
66
            'scheme' => isset($parsed['scheme']) ? $parsed['scheme'] : parse_url($this->base, PHP_URL_SCHEME),
67
            'host' => isset($parsed['host']) ? $parsed['host'] : $parsed['path'],
68
        ];
69
        $new['port'] = isset($parsed['port']) ? $parsed['port'] : getservbyname($new['scheme'], 'tcp');
70
        return $this->base == $new['scheme'] . '://' . $new['host'] . ':' . $new['port'];
71
    }
72
73
    /**
74
     * Get Host
75
     *
76
     * @return string|null
77
     */
78
    public function get()
79
    {
80
        return isset($this->host[0]) ? $this->host[0] : null;
81
    }
82
83
    /**
84
     * Get Host, falls back to Effective Request URI if not found
85
     *
86
     * @return string
87
     */
88
    public function getWithFallback()
89
    {
90
        if (($get = $this->get()) !== null) {
91
            // Host defined by the Host directive
92
            return $get;
93
        } elseif (
94
            $this->base !== $this->effective &&
95
            parse_url($this->base, PHP_URL_HOST) === ($host = parse_url($this->effective, PHP_URL_HOST))
96
        ) {
97
            // Host is the same, but Scheme or Port is different
98
            return getservbyname($scheme = parse_url($this->effective, PHP_URL_SCHEME), 'tcp') === parse_url($this->effective, PHP_URL_PORT) ? $scheme . '://' . $host : $this->effective;
99
        }
100
        // Return Host name only
101
        return parse_url($this->effective, PHP_URL_HOST);
102
    }
103
104
    /**
105
     * Is host listed by directive
106
     *
107
     * @param string $uri
108
     * @return bool
109
     */
110
    public function isUriListed($uri)
111
    {
112
        $uriParser = new UriParser($uri);
113
        $uri = mb_strtolower($uriParser->encode());
114
        $parts = [
115
            'scheme' => parse_url($uri, PHP_URL_SCHEME),
116
            'host' => parse_url($uri, PHP_URL_HOST),
117
        ];
118
        $parts['port'] = is_int($port = parse_url($uri, PHP_URL_PORT)) ? $port : getservbyname($parts['scheme'], 'tcp');
119
        $cases = [
120
            $parts['host'],
121
            $parts['host'] . ':' . $parts['port'],
122
            $parts['scheme'] . '://' . $parts['host'],
123
            $parts['scheme'] . '://' . $parts['host'] . ':' . $parts['port']
124
        ];
125
        foreach ($this->host as $host) {
126
            if (in_array($host, $cases)) {
127
                return true;
128
            }
129
        }
130
        return false;
131
    }
132
133
    /**
134
     * Export
135
     *
136
     * @return string[]|string|null
137
     */
138
    public function export()
139
    {
140
        if ($this->parent === null) {
141
            return isset($this->host[0]) ? $this->host[0] : null;
142
        }
143
        return $this->host;
144
    }
145
}
146