Url   A
last analyzed

Complexity

Total Complexity 7

Size/Duplication

Total Lines 79
Duplicated Lines 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
eloc 17
c 4
b 0
f 0
dl 0
loc 79
rs 10
wmc 7

2 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A isValid() 0 25 6
1
<?php
2
3
namespace Kontrolio\Rules\Core;
4
5
use Kontrolio\Rules\AbstractRule;
6
7
/**
8
 * URL validation rule.
9
 *
10
 * @package Kontrolio\Rules\Core
11
 */
12
class Url extends AbstractRule
13
{
14
    /**
15
     * Url validation pattern.
16
     *
17
     * @see https://github.com/symfony/symfony/blob/master/src/Symfony/Component/Validator/Constraints/UrlValidator.php
18
     */
19
    const PATTERN = '~^
20
            (%s)://                                 # protocol
21
            (([\pL\pN\-]+:)?([\pL\pN\-]+)@)?          # basic auth
22
            (
23
                ([\pL\pN\pS\-\.])+(\.?([\pL]|xn\-\-[\pL\pN\-]+)+\.?) # a domain name
24
                    |                                                # or
25
                \d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}                   # a IP address
26
                    |                                                # or
27
                \[
28
                    (?:(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){6})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:::(?:(?:(?:[0-9a-f]{1,4})):){5})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){4})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,1}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){3})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,2}(?:(?:[0-9a-f]{1,4})))?::(?:(?:(?:[0-9a-f]{1,4})):){2})(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,3}(?:(?:[0-9a-f]{1,4})))?::(?:(?:[0-9a-f]{1,4})):)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,4}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:(?:(?:(?:[0-9a-f]{1,4})):(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9]))\.){3}(?:(?:25[0-5]|(?:[1-9]|1[0-9]|2[0-4])?[0-9])))))))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,5}(?:(?:[0-9a-f]{1,4})))?::)(?:(?:[0-9a-f]{1,4})))|(?:(?:(?:(?:(?:(?:[0-9a-f]{1,4})):){0,6}(?:(?:[0-9a-f]{1,4})))?::))))
29
                \]  # a IPv6 address
30
            )
31
            (:[0-9]+)?                              # a port (optional)
32
            (/?|/\S+|\?\S*|\#\S*)                   # a /, nothing, a / with something, a query or a fragment
33
        $~ixu';
34
35
    /**
36
     * Checked protocols.
37
     *
38
     * @var array
39
     */
40
    private $protocols = ['http', 'https'];
41
42
    /**
43
     * Indicates whether DNS will be checked.
44
     *
45
     * @var bool
46
     */
47
    private $checkDNS;
48
49
    /**
50
     * Url constructor.
51
     *
52
     * @param bool $checkDNS
53
     */
54
    public function __construct($checkDNS = false)
55
    {
56
        $this->checkDNS = $checkDNS;
57
    }
58
59
    /**
60
     * Validates input.
61
     *
62
     * @param mixed $input
63
     *
64
     * @return bool
65
     */
66
    public function isValid($input = null)
67
    {
68
        if ($input === null || $input === '') {
69
            return false;
70
        }
71
72
        $pattern = sprintf(static::PATTERN, implode('|', $this->protocols));
73
74
        if (!preg_match($pattern, $input)) {
75
            $this->violations[] = 'url';
76
77
            return false;
78
        }
79
80
        if ($this->checkDNS) {
81
            $host = parse_url($input, PHP_URL_HOST);
82
83
            if (!checkdnsrr($host, 'ANY')) {
84
                $this->violations[] = 'dns';
85
86
                return false;
87
            }
88
        }
89
90
        return true;
91
    }
92
}
93