Completed
Push — master ( 7f24e1...cf8767 )
by ignace nyamagana
06:36
created

ImmutableComponentTrait   A

Complexity

Total Complexity 9

Size/Duplication

Total Lines 106
Duplicated Lines 0 %

Coupling/Cohesion

Components 2
Dependencies 2

Test Coverage

Coverage 88%

Importance

Changes 11
Bugs 1 Features 0
Metric Value
wmc 9
c 11
b 1
f 0
lcom 2
cbo 2
dl 0
loc 106
ccs 22
cts 25
cp 0.88
rs 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
getUriComponent() 0 1 ?
__toString() 0 1 ?
A assertValidComponent() 0 6 3
A sameValueAs() 0 4 1
A getReservedRegex() 0 8 2
A encode() 0 14 1
A modify() 0 8 2
1
<?php
2
/**
3
 * League.Url (http://url.thephpleague.com)
4
 *
5
 * @package   League.url
6
 * @author    Ignace Nyamagana Butera <[email protected]>
7
 * @copyright 2013-2015 Ignace Nyamagana Butera
8
 * @license   https://github.com/thephpleague/uri/blob/master/LICENSE (MIT License)
9
 * @version   4.0.0
10
 * @link      https://github.com/thephpleague/uri/
11
 */
12
namespace League\Uri\Types;
13
14
use InvalidArgumentException;
15
use League\Uri\Interfaces\UriPart;
16
use ReflectionClass;
17
18
/**
19
 * Common methods for Component Value Object
20
 *
21
 * @package League.uri
22
 * @author  Ignace Nyamagana Butera <[email protected]>
23
 * @since   4.0.0
24
 */
25
trait ImmutableComponentTrait
26
{
27
    use ValidatorTrait;
28
29
    /**
30
     * Characters to conform to RFC3986 - http://tools.ietf.org/html/rfc3986#section-2
31
     *
32
     * @var array
33
     */
34
    protected static $characters_set = [
35
        '!', '$', '&', "'", '(', ')', '*', '+', ',', ';', '=', ':',
36
    ];
37
38
    protected static $characters_set_compiled;
39
40
    /**
41
     * Encoded characters to conform to RFC3986 - http://tools.ietf.org/html/rfc3986#section-2
42
     *
43
     * @var array
44
     */
45
    protected static $characters_set_encoded = [
46
        '%21', '%24', '%26', '%27', '%28', '%29', '%2A', '%2B', '%2C', '%3B', '%3D', '%3A',
47
    ];
48
49
    /**
50
     * Invalid Characters list
51
     *
52
     * @var string
53
     */
54
    protected static $invalidCharactersRegex;
55
56
    /**
57
     * Check the string against RFC3986 rules
58
     *
59
     * @param string $str
60
     *
61
     * @throws InvalidArgumentException If the string is invalid
62
     */
63 864
    protected function assertValidComponent($str)
64
    {
65 864
        if (!empty(static::$invalidCharactersRegex) && preg_match(static::$invalidCharactersRegex, $str)) {
66 26
            throw new InvalidArgumentException('The component contains invalid characters');
67
        }
68 838
    }
69
70
    /**
71
     * @inheritdoc
72
     */
73 24
    public function sameValueAs(UriPart $component)
74
    {
75 24
        return $component->getUriComponent() === $this->getUriComponent();
76
    }
77
78
    /**
79
     * @inheritdoc
80
     */
81
    abstract public function getUriComponent();
82
83
    /**
84
     * @inheritdoc
85
     */
86
    abstract public function __toString();
87
88 852
    protected static function getReservedRegex()
89
    {
90 852
        if (!isset(static::$characters_set_compiled)) {
91
            $reserved = preg_quote(implode('', static::$characters_set), '/');
92
            static::$characters_set_compiled = '/(?:[^'.$reserved.']+|%(?![A-Fa-f0-9]{2}))/S';
93
        }
94 852
        return static::$characters_set_compiled;
95
    }
96
97
    /**
98
     * Encoding string according to RFC3986
99
     *
100
     * @param string $value
101
     *
102
     * @return string
103
     */
104 816
    protected static function encode($value)
105
    {
106 816
        $str = preg_replace_callback(
107 816
            self::getReservedRegex(),
108
            function (array $matches) {
109 738
                return rawurlencode($matches[0]);
110 816
            },
111
            $value
112 816
        );
113
114 816
        return preg_replace_callback(',(?<encode>%[0-9a-f]{2}),', function (array $matches) {
115 76
            return strtoupper($matches['encode']);
116 816
        }, $str);
117
    }
118
119
    /**
120
     * @inheritdoc
121
     */
122 356
    public function modify($value)
123
    {
124 356
        if ($value == $this->__toString()) {
125 118
            return $this;
126
        }
127
128 316
        return (new ReflectionClass(get_called_class()))->newInstance($value);
129
    }
130
}
131