Completed
Push — master ( cb65dd...97cb3a )
by Jan-Petter
02:28
created

HostClient::getWithFallback()   B

Complexity

Conditions 5
Paths 4

Size

Total Lines 15
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

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