Authority::explodeAuthority()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 18
ccs 12
cts 12
cp 1
rs 9.4285
cc 2
eloc 11
nc 2
nop 1
crap 2
1
<?php
2
namespace Subreality\Dilmun\Anshar\Http\UriParts;
3
4
/**
5
 * Class Authority
6
 * @package Subreality\Dilmun\Anshar\Http\UriParts
7
 */
8
class Authority extends AbstractUriPart
9
{
10
    /** @var  UserInfo */
11
    protected $user_info;
12
    /** @var  Host */
13
    protected $host;
14
    /** @var  Port */
15
    protected $port;
16
17
    protected $authority_parts = array(
18
        "user_info" => "",
19
        "host"      => "",
20
        "port"      => null,
21
    );
22
23
    protected static $part_pattern;
24
    protected static $valid_pattern;
25
26
    /** @noinspection PhpMissingParentConstructorInspection */
27
    /**
28
     * Authority constructor. Accepts a string representing a URI authority component. Construction will throw an
29
     * exception if the authority is not a string.
30
     *
31
     * Construction splits a given authority string into its component objects, UserInfo, Host, and Port, whose
32
     * individual constructors may throw exceptions provided invalid component strings.
33
     *
34
     * Construction accepts strings for UserInfo and Host that have been percent-encoded as well as strings that have
35
     * not been percent-encoded and will encode invalid characters.
36
     *
37
     * Construction with a string that includes both encoded and decoded characters will be assumed to be an encoded
38
     * string, resulting in double-encoding.
39
     *
40
     * authority = [ userinfo "@" ] host [ ":" port ]
41
     *
42
     * @see UserInfo
43
     * @see Host
44
     * @see Port
45
     * @see https://tools.ietf.org/html/rfc3986#appendix-A
46
     *
47
     * @throws \InvalidArgumentException given a non-string
48
     *
49
     * @param string $authority A string representing a URI authority
50
     */
51 110
    public function __construct($authority)
52
    {
53 110
        if (!is_string($authority)) {
54 12
            throw new \InvalidArgumentException("Authority must be a string");
55
        } else {
56 98
            $exploded_authority = $this->explodeAuthority($authority);
57
58 98
            $this->authority_parts = array_merge($this->authority_parts, $exploded_authority);
59
60 98
            $this->user_info = new UserInfo($this->authority_parts["user_info"]);
61 98
            $this->host      = new Host($this->authority_parts["host"]);
62 98
            $this->port      = new Port($this->authority_parts["port"]);
63
        }
64 97
    }
65
66
    /**
67
     * Returns the authority's UserInfo object
68
     *
69
     * @return UserInfo
70
     */
71 97
    public function getUserInfo()
72
    {
73 97
        return $this->user_info;
74
    }
75
76
    /**
77
     * Returns the authority's Host object
78
     *
79
     * @return Host
80
     */
81 96
    public function getHost()
82
    {
83 96
        return $this->host;
84
    }
85
86
    /**
87
     * Returns the authority's Port object
88
     *
89
     * @return Port
90
     */
91 97
    public function getPort()
92
    {
93 97
        return $this->port;
94
    }
95
96
    /**
97
     * Returns a string representation of the authority
98
     *
99
     * @return string   A string representation of the authority
100
     */
101 33
    public function __toString()
102
    {
103 33
        return $this->user_info->toUriString() . $this->host->toUriString() . $this->port->toUriString();
104
    }
105
106
    /**
107
     * Returns a string representation of the authority formatted so that it can be compiled into a complete URI string
108
     * per the Uri object's string specification.
109
     *
110
     * If the user info is empty, toUriString returns an authority string with no user info; otherwise, toUriString
111
     * returns the user info suffixed with an at symbol.
112
     *
113
     * If the port is empty, toUriString returns an authority string with no port; otherwise, toUriString returns the
114
     * port prefixed with a colon.
115
     *
116
     * If the authority overall is empty, toUriString returns an empty string; otherwise, toUriString returns the entire
117
     * authority string prefixed with two slashes.
118
     *
119
     * toUriString will also check the port against an optionally-provided scheme; if the port is standard for the given
120
     * scheme, toUriString will not include the port within the authority string.
121
     *
122
     * @see Uri::__toString
123
     *
124
     * @param Scheme|null $scheme   [optional] A scheme against which to check if the port is the standard
125
     *
126
     * @return string               A string representation of the authority formatted for a complete URI string
127
     */
128 37
    public function toUriString(Scheme $scheme = null)
129 37
    {
130 19
        $authority_string = $this->user_info->toUriString() .
131 19
            $this->host->toUriString() .
132 19
            $this->port->toUriString($scheme);
133
134 19
        if (!empty($authority_string)) {
135 16
            $authority_string = "//" . $authority_string;
136 16
        }
137
138 19
        return $authority_string;
139
    }
140
141
    /**
142
     * Compiles a valid pattern for an authority based upon valid patterns for user info, host, and port.
143
     *
144
     * @return void
145
     */
146 16
    protected static function compileValidPattern()
147
    {
148 16
        $user_info_pattern = UserInfo::getValidPattern();
149 16
        $host_pattern      = Host::getValidPattern();
150 16
        $port_pattern      = Port::getValidPattern();
151
152 16
        $reg_start = '/^$|^';   //allow for empty authority
153 16
        $reg_end   = '$/';
154
155 16
        self::$part_pattern =
156 16
            '((?\'user_info\'' . $user_info_pattern . ')@)?' .
157 16
            '(?\'host\'' . $host_pattern . ')' .
158 16
            '(:(?\'port\'' . $port_pattern . '))?';
159
160 16
        self::$valid_pattern = $reg_start . self::$part_pattern . $reg_end;
161 16
    }
162
163
    /**
164
     * Splits URI authority data into user info, host, and port data, returning an array with named keys.
165
     *
166
     * For the host component, it will capture everything within brackets to support ipv6 or match all characters until
167
     * it finds a colon indicating the start of the port component.
168
     *
169
     * @param string $authority     The authority part of a URI to be decomposed
170
     * @return mixed[]              An array with named keys containing the component parts of the supplied
0 ignored issues
show
Documentation introduced by
Should the return type not be array<*,string|integer|null>?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
171
     *                              authority
172
     */
173 98
    protected function explodeAuthority($authority)
174
    {
175 98
        $reg_start      = '/^';
176 98
        $user_info_part = '(?:(?\'user_info\'.+)@)?';
177 98
        $host_part      = '(?\'host\'\[.+\]|.[^:]+)';
178 98
        $port_part      = '(?::(?\'port\'[0-9]+))?';
179 98
        $reg_end        = '/';
180
181 98
        $authority_syntax = $reg_start . $user_info_part . $host_part . $port_part . $reg_end;
182
183 98
        preg_match($authority_syntax, $authority, $authority_parts);
184
185 98
        if (isset($authority_parts["port"])) {
186 48
            $authority_parts["port"] = (int) $authority_parts["port"];
187 48
        }
188
189 98
        return $authority_parts;
190
    }
191
}
192