URISchemes::resolveSchemeName()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 2
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
nc 1
nop 1
1
<?php
2
/**
3
 * @package AppUtils
4
 * @subpackage URLInfo
5
 * @see \AppUtils\URLInfo\URISchemes
6
 */
7
8
declare(strict_types=1);
9
10
namespace AppUtils\URLInfo;
11
12
/**
13
 * Class URLInfo_Schemes
14
 *
15
 * @package AppUtils
16
 * @subpackage URLInfo
17
 * @author Sebastian Mordziol <[email protected]>
18
 *
19
 * @link https://en.wikipedia.org/wiki/List_of_URI_schemes
20
 */
21
class URISchemes
22
{
23
    public const ERROR_INVALID_SCHEME = 113601;
24
25
    /**
26
     * @var string[]
27
     */
28
    private static array $schemes = array(
29
        'bitcoin:',
30
        'callto:',
31
        'chrome://',
32
        'data:',
33
        'dns:',
34
        'dns://',
35
        'ed2k://',
36
        'facetime://',
37
        'feed:',
38
        'feed://',
39
        'file://',
40
        'file://',
41
        'ftp://',
42
        'geo:',
43
        'git://',
44
        'http://',
45
        'https://',
46
        'im:',
47
        'ldap://',
48
        'ldaps://',
49
        'magnet:',
50
        'mailto:',
51
        'sftp://',
52
        'smb://',
53
        'sms:',
54
        'ssh://',
55
        'steam://',
56
        'steam:', // command line URI
57
        'svn+ssh:',
58
        'svn:',
59
        'teamspeak://',
60
        'tel:',
61
        'telnet://',
62
        'udp://',
63
        'vnc://',
64
        'xmpp:',
65
    );
66
67
    /**
68
     * Tries to detect a valid scheme in the specified URL,
69
     * using the internal list of known schemes.
70
     *
71
     * @param string $url
72
     * @return string|null
73
     */
74
    public static function detectScheme(string $url) : ?string
75
    {
76
        foreach(self::$schemes as $scheme) {
77
            if(stripos($url, $scheme) === 0) {
78
                return $scheme;
79
            }
80
        }
81
82
        return null;
83
    }
84
85
    /**
86
     * @var string[]|null
87
     */
88
    private static ?array $schemeNames = null;
89
90
    /**
91
     * @return string[]
92
     */
93
    public static function getSchemeNames() : array
94
    {
95
        if(isset(self::$schemeNames)) {
96
            return self::$schemeNames;
97
        }
98
99
        self::$schemeNames = array();
100
101
        foreach(self::$schemes as $scheme) {
102
            self::$schemeNames[] = self::resolveSchemeName($scheme);
103
        }
104
105
        return self::$schemeNames;
0 ignored issues
show
Bug Best Practice introduced by
The expression return self::schemeNames returns the type null which is incompatible with the type-hinted return array.
Loading history...
106
    }
107
108
    public static function resolveSchemeName(string $scheme) : string
109
    {
110
        $parts = explode(':', $scheme);
111
        return array_shift($parts);
112
    }
113
114
    /**
115
     * @return string[]
116
     */
117
    public static function getSchemes() : array
118
    {
119
        return self::$schemes;
120
    }
121
122
    /**
123
     * Adds a scheme to the list of known schemes, so it can be
124
     * detected correctly.
125
     *
126
     * @param string $scheme
127
     * @return void
128
     * @throws URLException
129
     */
130
    public static function addScheme(string $scheme) : void
131
    {
132
        self::requireValidScheme($scheme);
133
134
        if(!in_array($scheme, self::$schemes, true))
135
        {
136
            self::$schemes[] = $scheme;
137
        }
138
139
        self::resetCache();
140
    }
141
142
    public static function requireValidScheme(string $scheme) : void
143
    {
144
        if(strpos($scheme, ':'))
145
        {
146
            return;
147
        }
148
149
        throw new URLException(
150
            'Cannot add scheme, invalid format.',
151
            sprintf(
152
                'The scheme [%s] is missing the colon separator character. Example: https://.',
153
                $scheme
154
            ),
155
            self::ERROR_INVALID_SCHEME
156
        );
157
    }
158
159
    public static function isValidScheme(string $scheme) : bool
160
    {
161
        return in_array(strtolower($scheme), self::$schemes, true);
162
    }
163
164
    public static function isValidSchemeName(string $scheme) : bool
165
    {
166
        return in_array(strtolower($scheme), self::getSchemeNames(), true);
167
    }
168
169
    public static function removeScheme(string $targetScheme) : void
170
    {
171
        self::$schemes = array_filter(
172
            self::$schemes,
173
            static fn($scheme) => $scheme !== $targetScheme
174
        );
175
176
        self::resetCache();
177
    }
178
179
    /**
180
     * Resets the cached scheme names. Used after the schemes
181
     * list has been modified.
182
     *
183
     * @return void
184
     */
185
    private static function resetCache() : void
186
    {
187
        self::$schemeNames = null;
188
    }
189
}
190