Passed
Push — master ( 915f8b...f333c5 )
by
unknown
10:12
created

validateUrlSyntax()   F

Complexity

Conditions 32
Paths > 20000

Size

Total Lines 194
Code Lines 110

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 32
eloc 110
c 0
b 0
f 0
nc 36372480
nop 2
dl 0
loc 194
rs 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
/* Source: https://github.com/moodle/moodle/blob/MOODLE_310_STABLE/lib/validateurlsyntax.php under GNU/GPL license */
4
5
declare(strict_types=1);
6
7
namespace Chamilo\CourseBundle\Component\CourseCopy\CommonCartridge\Import\Lib;
8
9
use const E_USER_ERROR;
10
11
/**
12
 *  BEGINNING OF validateUrlSyntax() function.
13
 *
14
 * @param mixed $urladdr
15
 * @param mixed $options
16
 */
17
function validateUrlSyntax($urladdr, $options = '')
18
{
19
    // Force Options parameter to be lower case
20
    // DISABLED PERMAMENTLY - OK to remove from code
21
    //    $options = strtolower($options);
22
23
    // Check Options Parameter
24
    if (!preg_match('/^([sHSEFRuPaIpfqr][+?-])*$/', $options)) {
25
        trigger_error('Options attribute malformed', E_USER_ERROR);
26
    }
27
28
    // Set Options Array, set defaults if options are not specified
29
    // Scheme
30
    if (!str_contains($options, 's')) {
31
        $aOptions['s'] = '?';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$aOptions was never initialized. Although not strictly required by PHP, it is generally a good practice to add $aOptions = array(); before regardless.
Loading history...
32
    } else {
33
        $aOptions['s'] = substr($options, strpos($options, 's') + 1, 1);
34
    }
35
    // http://
36
    if (!str_contains($options, 'H')) {
37
        $aOptions['H'] = '?';
38
    } else {
39
        $aOptions['H'] = substr($options, strpos($options, 'H') + 1, 1);
40
    }
41
    // https:// (SSL)
42
    if (!str_contains($options, 'S')) {
43
        $aOptions['S'] = '?';
44
    } else {
45
        $aOptions['S'] = substr($options, strpos($options, 'S') + 1, 1);
46
    }
47
    // mailto: (email)
48
    if (!str_contains($options, 'E')) {
49
        $aOptions['E'] = '-';
50
    } else {
51
        $aOptions['E'] = substr($options, strpos($options, 'E') + 1, 1);
52
    }
53
    // ftp://
54
    if (!str_contains($options, 'F')) {
55
        $aOptions['F'] = '-';
56
    } else {
57
        $aOptions['F'] = substr($options, strpos($options, 'F') + 1, 1);
58
    }
59
    // rtmp://
60
    if (!str_contains($options, 'R')) {
61
        $aOptions['R'] = '-';
62
    } else {
63
        $aOptions['R'] = substr($options, strpos($options, 'R') + 1, 1);
64
    }
65
    // User section
66
    if (!str_contains($options, 'u')) {
67
        $aOptions['u'] = '?';
68
    } else {
69
        $aOptions['u'] = substr($options, strpos($options, 'u') + 1, 1);
70
    }
71
    // Password in user section
72
    if (!str_contains($options, 'P')) {
73
        $aOptions['P'] = '?';
74
    } else {
75
        $aOptions['P'] = substr($options, strpos($options, 'P') + 1, 1);
76
    }
77
    // Address Section
78
    if (!str_contains($options, 'a')) {
79
        $aOptions['a'] = '+';
80
    } else {
81
        $aOptions['a'] = substr($options, strpos($options, 'a') + 1, 1);
82
    }
83
    // IP Address in address section
84
    if (!str_contains($options, 'I')) {
85
        $aOptions['I'] = '?';
86
    } else {
87
        $aOptions['I'] = substr($options, strpos($options, 'I') + 1, 1);
88
    }
89
    // Port number
90
    if (!str_contains($options, 'p')) {
91
        $aOptions['p'] = '?';
92
    } else {
93
        $aOptions['p'] = substr($options, strpos($options, 'p') + 1, 1);
94
    }
95
    // File Path
96
    if (!str_contains($options, 'f')) {
97
        $aOptions['f'] = '?';
98
    } else {
99
        $aOptions['f'] = substr($options, strpos($options, 'f') + 1, 1);
100
    }
101
    // Query Section
102
    if (!str_contains($options, 'q')) {
103
        $aOptions['q'] = '?';
104
    } else {
105
        $aOptions['q'] = substr($options, strpos($options, 'q') + 1, 1);
106
    }
107
    // Fragment (Anchor)
108
    if (!str_contains($options, 'r')) {
109
        $aOptions['r'] = '?';
110
    } else {
111
        $aOptions['r'] = substr($options, strpos($options, 'r') + 1, 1);
112
    }
113
114
    // Loop through options array, to search for and replace "-" to "{0}" and "+" to ""
115
    foreach ($aOptions as $key => $value) {
116
        if ('-' == $value) {
117
            $aOptions[$key] = '{0}';
118
        }
119
        if ('+' == $value) {
120
            $aOptions[$key] = '';
121
        }
122
    }
123
124
    // DEBUGGING - Unescape following line to display to screen current option values
125
    // echo '<pre>'; print_r($aOptions); echo '</pre>';
126
127
    // Preset Allowed Characters
128
    $alphanum = '[a-zA-Z0-9]';  // Alpha Numeric
129
    $unreserved = '[a-zA-Z0-9_.!~*\'()-]';
130
    $escaped = '(%[0-9a-fA-F]{2})'; // Escape sequence - In Hex - %6d would be a 'm'
131
    $reserved = '[;/?:@&=+$,]'; // Special characters in the URI
132
133
    // Beginning Regular Expression
134
    // Scheme - Allows for 'http://', 'https://', 'mailto:', 'ftp://' or 'rtmp://'
135
    $scheme = '(';
136
    if ('' === $aOptions['H']) {
137
        $scheme .= 'http://';
138
    } elseif ('' === $aOptions['S']) {
139
        $scheme .= 'https://';
140
    } elseif ('' === $aOptions['E']) {
141
        $scheme .= 'mailto:';
142
    } elseif ('' === $aOptions['F']) {
143
        $scheme .= 'ftp://';
144
    } elseif ('' === $aOptions['R']) {
145
        $scheme .= 'rtmp://';
146
    } else {
147
        if ('?' === $aOptions['H']) {
148
            $scheme .= '|(http://)';
149
        }
150
        if ('?' === $aOptions['S']) {
151
            $scheme .= '|(https://)';
152
        }
153
        if ('?' === $aOptions['E']) {
154
            $scheme .= '|(mailto:)';
155
        }
156
        if ('?' === $aOptions['F']) {
157
            $scheme .= '|(ftp://)';
158
        }
159
        if ('?' === $aOptions['R']) {
160
            $scheme .= '|(rtmp://)';
161
        }
162
        $scheme = str_replace('(|', '(', $scheme); // fix first pipe
163
    }
164
    $scheme .= ')'.$aOptions['s'];
165
    // End setting scheme
166
167
    // User Info - Allows for 'username@' or 'username:password@'. Note: contrary to rfc, I removed ':' from username section, allowing it only in password.
168
    $userinfo = '(('.$unreserved.'|'.$escaped.'|[;&=+$,])+(:('.$unreserved.'|'.$escaped.'|[;:&=+$,])+)'.$aOptions['P'].'@)'.$aOptions['u'];
169
170
    // IP ADDRESS - Allows 0.0.0.0 to 255.255.255.255
171
    $ipaddress = '((((2(([0-4][0-9])|(5[0-5])))|([01]?[0-9]?[0-9]))\.){3}((2(([0-4][0-9])|(5[0-5])))|([01]?[0-9]?[0-9])))';
172
173
    // Tertiary Domain(s) - Optional - Multi - Although some sites may use other characters, the RFC says tertiary domains have the same naming restrictions as second level domains
174
    $domain_tertiary = '('.$alphanum.'(([a-zA-Z0-9-]{0,62})'.$alphanum.')?\.)*';
175
    $domain_toplevel = '([a-zA-Z](([a-zA-Z0-9-]*)[a-zA-Z0-9])?)';
176
177
    if ('{0}' === $aOptions['I']) {       // IP Address Not Allowed
178
        $address = '('.$domain_tertiary. /* MDL-9295 $domain_secondary . */ $domain_toplevel.')';
179
    } elseif ('' === $aOptions['I']) {  // IP Address Required
180
        $address = '('.$ipaddress.')';
181
    } else {                            // IP Address Optional
182
        $address = '(('.$ipaddress.')|('.$domain_tertiary. /* MDL-9295 $domain_secondary . */ $domain_toplevel.'))';
183
    }
184
    $address .= $aOptions['a'];
185
186
    // Port Number - :80 or :8080 or :65534 Allows range of :0 to :65535
187
    //    (0-59999)         |(60000-64999)   |(65000-65499)    |(65500-65529)  |(65530-65535)
188
    $port_number = '(:(([0-5]?[0-9]{1,4})|(6[0-4][0-9]{3})|(65[0-4][0-9]{2})|(655[0-2][0-9])|(6553[0-5])))'.$aOptions['p'];
189
190
    // Path - Can be as simple as '/' or have multiple folders and filenames
191
    $path = '(/((;)?('.$unreserved.'|'.$escaped.'|[:@&=+$,])+(/)?)*)'.$aOptions['f'];
192
193
    // Query Section - Accepts ?var1=value1&var2=value2 or ?2393,1221 and much more
194
    $querystring = '(\?('.$reserved.'|'.$unreserved.'|'.$escaped.')*)'.$aOptions['q'];
195
196
    // Fragment Section - Accepts anchors such as #top
197
    $fragment = '(\#('.$reserved.'|'.$unreserved.'|'.$escaped.')*)'.$aOptions['r'];
198
199
    // Building Regular Expression
200
    $regexp = '#^'.$scheme.$userinfo.$address.$port_number.$path.$querystring.$fragment.'$#i';
201
202
    // DEBUGGING - Uncomment Line Below To Display The Regular Expression Built
203
    // echo '<pre>' . htmlentities(wordwrap($regexp,70,"\n",1)) . '</pre>';
204
205
    // Running the regular expression
206
    if (preg_match($regexp, $urladdr)) {
207
        return true; // The domain passed
208
    }
209
210
    return false; // The domain didn't pass the expression
211
}
212
213
/**
214
 * About ValidateEmailSyntax():
215
 * This function uses the ValidateUrlSyntax() function to easily check the
216
 * syntax of an email address. It accepts the same options as ValidateURLSyntax
217
 * but defaults them for email addresses.
218
 *
219
 *  Released under same license as validateUrlSyntax()
220
 *
221
 * @param mixed $emailaddr
222
 * @param mixed $options
223
 */
224
function validateEmailSyntax($emailaddr, $options = '')
225
{
226
    // Check Options Parameter
227
    if (!preg_match('/^([sHSEFuPaIpfqr][+?-])*$/', $options)) {
228
        trigger_error('Options attribute malformed', E_USER_ERROR);
229
    }
230
231
    // Set Options Array, set defaults if options are not specified
232
    // Scheme
233
    if (!str_contains($options, 's')) {
234
        $aOptions['s'] = '-';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$aOptions was never initialized. Although not strictly required by PHP, it is generally a good practice to add $aOptions = array(); before regardless.
Loading history...
235
    } else {
236
        $aOptions['s'] = substr($options, strpos($options, 's') + 1, 1);
237
    }
238
    // http://
239
    if (!str_contains($options, 'H')) {
240
        $aOptions['H'] = '-';
241
    } else {
242
        $aOptions['H'] = substr($options, strpos($options, 'H') + 1, 1);
243
    }
244
    // https:// (SSL)
245
    if (!str_contains($options, 'S')) {
246
        $aOptions['S'] = '-';
247
    } else {
248
        $aOptions['S'] = substr($options, strpos($options, 'S') + 1, 1);
249
    }
250
    // mailto: (email)
251
    if (!str_contains($options, 'E')) {
252
        $aOptions['E'] = '?';
253
    } else {
254
        $aOptions['E'] = substr($options, strpos($options, 'E') + 1, 1);
255
    }
256
    // ftp://
257
    if (!str_contains($options, 'F')) {
258
        $aOptions['F'] = '-';
259
    } else {
260
        $aOptions['F'] = substr($options, strpos($options, 'F') + 1, 1);
261
    }
262
    // User section
263
    if (!str_contains($options, 'u')) {
264
        $aOptions['u'] = '+';
265
    } else {
266
        $aOptions['u'] = substr($options, strpos($options, 'u') + 1, 1);
267
    }
268
    // Password in user section
269
    if (!str_contains($options, 'P')) {
270
        $aOptions['P'] = '-';
271
    } else {
272
        $aOptions['P'] = substr($options, strpos($options, 'P') + 1, 1);
273
    }
274
    // Address Section
275
    if (!str_contains($options, 'a')) {
276
        $aOptions['a'] = '+';
277
    } else {
278
        $aOptions['a'] = substr($options, strpos($options, 'a') + 1, 1);
279
    }
280
    // IP Address in address section
281
    if (!str_contains($options, 'I')) {
282
        $aOptions['I'] = '-';
283
    } else {
284
        $aOptions['I'] = substr($options, strpos($options, 'I') + 1, 1);
285
    }
286
    // Port number
287
    if (!str_contains($options, 'p')) {
288
        $aOptions['p'] = '-';
289
    } else {
290
        $aOptions['p'] = substr($options, strpos($options, 'p') + 1, 1);
291
    }
292
    // File Path
293
    if (!str_contains($options, 'f')) {
294
        $aOptions['f'] = '-';
295
    } else {
296
        $aOptions['f'] = substr($options, strpos($options, 'f') + 1, 1);
297
    }
298
    // Query Section
299
    if (!str_contains($options, 'q')) {
300
        $aOptions['q'] = '-';
301
    } else {
302
        $aOptions['q'] = substr($options, strpos($options, 'q') + 1, 1);
303
    }
304
    // Fragment (Anchor)
305
    if (!str_contains($options, 'r')) {
306
        $aOptions['r'] = '-';
307
    } else {
308
        $aOptions['r'] = substr($options, strpos($options, 'r') + 1, 1);
309
    }
310
311
    // Generate options
312
    $newoptions = '';
313
    foreach ($aOptions as $key => $value) {
314
        $newoptions .= $key.$value;
315
    }
316
317
    // DEBUGGING - Uncomment line below to display generated options
318
    // echo '<pre>' . $newoptions . '</pre>';
319
320
    // Send to validateUrlSyntax() and return result
321
    return validateUrlSyntax($emailaddr, $newoptions);
322
}
323
324
/**
325
 * About ValidateFtpSyntax():
326
 * This function uses the ValidateUrlSyntax() function to easily check the
327
 * syntax of an FTP address. It accepts the same options as ValidateURLSyntax
328
 * but defaults them for FTP addresses.
329
 *
330
 * @param mixed $ftpaddr
331
 * @param mixed $options
332
 */
333
function validateFtpSyntax($ftpaddr, $options = '')
334
{
335
    // Check Options Parameter
336
    if (!preg_match('/^([sHSEFuPaIpfqr][+?-])*$/', $options)) {
337
        trigger_error('Options attribute malformed', E_USER_ERROR);
338
    }
339
340
    // Set Options Array, set defaults if options are not specified
341
    // Scheme
342
    if (!str_contains($options, 's')) {
343
        $aOptions['s'] = '?';
0 ignored issues
show
Comprehensibility Best Practice introduced by
$aOptions was never initialized. Although not strictly required by PHP, it is generally a good practice to add $aOptions = array(); before regardless.
Loading history...
344
    } else {
345
        $aOptions['s'] = substr($options, strpos($options, 's') + 1, 1);
346
    }
347
    // http://
348
    if (!str_contains($options, 'H')) {
349
        $aOptions['H'] = '-';
350
    } else {
351
        $aOptions['H'] = substr($options, strpos($options, 'H') + 1, 1);
352
    }
353
    // https:// (SSL)
354
    if (!str_contains($options, 'S')) {
355
        $aOptions['S'] = '-';
356
    } else {
357
        $aOptions['S'] = substr($options, strpos($options, 'S') + 1, 1);
358
    }
359
    // mailto: (email)
360
    if (!str_contains($options, 'E')) {
361
        $aOptions['E'] = '-';
362
    } else {
363
        $aOptions['E'] = substr($options, strpos($options, 'E') + 1, 1);
364
    }
365
    // ftp://
366
    if (!str_contains($options, 'F')) {
367
        $aOptions['F'] = '+';
368
    } else {
369
        $aOptions['F'] = substr($options, strpos($options, 'F') + 1, 1);
370
    }
371
    // User section
372
    if (!str_contains($options, 'u')) {
373
        $aOptions['u'] = '?';
374
    } else {
375
        $aOptions['u'] = substr($options, strpos($options, 'u') + 1, 1);
376
    }
377
    // Password in user section
378
    if (!str_contains($options, 'P')) {
379
        $aOptions['P'] = '?';
380
    } else {
381
        $aOptions['P'] = substr($options, strpos($options, 'P') + 1, 1);
382
    }
383
    // Address Section
384
    if (!str_contains($options, 'a')) {
385
        $aOptions['a'] = '+';
386
    } else {
387
        $aOptions['a'] = substr($options, strpos($options, 'a') + 1, 1);
388
    }
389
    // IP Address in address section
390
    if (!str_contains($options, 'I')) {
391
        $aOptions['I'] = '?';
392
    } else {
393
        $aOptions['I'] = substr($options, strpos($options, 'I') + 1, 1);
394
    }
395
    // Port number
396
    if (!str_contains($options, 'p')) {
397
        $aOptions['p'] = '?';
398
    } else {
399
        $aOptions['p'] = substr($options, strpos($options, 'p') + 1, 1);
400
    }
401
    // File Path
402
    if (!str_contains($options, 'f')) {
403
        $aOptions['f'] = '?';
404
    } else {
405
        $aOptions['f'] = substr($options, strpos($options, 'f') + 1, 1);
406
    }
407
    // Query Section
408
    if (!str_contains($options, 'q')) {
409
        $aOptions['q'] = '-';
410
    } else {
411
        $aOptions['q'] = substr($options, strpos($options, 'q') + 1, 1);
412
    }
413
    // Fragment (Anchor)
414
    if (!str_contains($options, 'r')) {
415
        $aOptions['r'] = '-';
416
    } else {
417
        $aOptions['r'] = substr($options, strpos($options, 'r') + 1, 1);
418
    }
419
420
    // Generate options
421
    $newoptions = '';
422
    foreach ($aOptions as $key => $value) {
423
        $newoptions .= $key.$value;
424
    }
425
426
    // Send to validateUrlSyntax() and return result
427
    return validateUrlSyntax($ftpaddr, $newoptions);
428
}
429