UrlEncoder   A
last analyzed

Complexity

Total Complexity 6

Size/Duplication

Total Lines 96
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 6
lcom 1
cbo 0
dl 0
loc 96
ccs 16
cts 16
cp 1
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A unescapeAndEncode() 0 6 1
A decode() 0 12 2
A encode() 0 17 3
1
<?php
2
3
/*
4
 * This file is part of the league/commonmark package.
5
 *
6
 * (c) Colin O'Dell <[email protected]>
7
 *
8
 * Original code based on the CommonMark JS reference parser (https://bitly.com/commonmark-js)
9
 *  - (c) John MacFarlane
10
 *
11
 * For the full copyright and license information, please view the LICENSE
12
 * file that was distributed with this source code.
13
 */
14
15
namespace League\CommonMark\Util;
16
17
final class UrlEncoder
18
{
19
    protected static $dontEncode = [
20
        '%21' => '!',
21
        '%23' => '#',
22
        '%24' => '$',
23
        '%26' => '&',
24
        '%27' => '\'',
25
        '%28' => '(',
26
        '%29' => ')',
27
        '%2A' => '*',
28
        '%2B' => '+',
29
        '%2C' => ',',
30
        '%2D' => '-',
31
        '%2E' => '.',
32
        '%2F' => '/',
33
        '%3A' => ':',
34
        '%3B' => ';',
35
        '%3D' => '=',
36
        '%3F' => '?',
37
        '%40' => '@',
38
        '%5F' => '_',
39
        '%7E' => '~',
40
    ];
41
42
    protected static $dontDecode = [
43
        ';',
44
        '/',
45
        '?',
46
        ':',
47
        '@',
48
        '&',
49
        '=',
50
        '+',
51
        '$',
52
        ',',
53
        '#',
54
    ];
55
56
    /**
57
     * @param string $uri
58
     *
59
     * @return string
60
     */
61 639
    public static function unescapeAndEncode(string $uri): string
62
    {
63 639
        $decoded = \html_entity_decode($uri);
64
65 639
        return self::encode(self::decode($decoded));
66
    }
67
68
    /**
69
     * Decode a percent-encoded URI
70
     *
71
     * @param string $uri
72
     *
73
     * @return string
74
     */
75 639
    private static function decode(string $uri): string
76
    {
77
        return \preg_replace_callback('/%([0-9a-f]{2})/iu', function ($matches) {
78 84
            $char = \chr(\hexdec($matches[1]));
79
80 84
            if (\in_array($char, self::$dontDecode, true)) {
81 39
                return \strtoupper($matches[0]);
82
            }
83
84 48
            return $char;
85 639
        }, $uri);
86
    }
87
88
    /**
89
     * Encode a URI, preserving already-encoded and excluded characters
90
     *
91
     * @param string $uri
92
     *
93
     * @return string
94
     */
95 639
    private static function encode(string $uri): string
96
    {
97
        return \preg_replace_callback('/(%[0-9a-f]{2})|./isu', function ($matches) {
98
            // Keep already-encoded characters as-is
99 630
            if (\count($matches) > 1) {
100 39
                return $matches[0];
101
            }
102
103
            // Keep excluded characters as-is
104 597
            if (\in_array($matches[0], self::$dontEncode)) {
105 525
                return $matches[0];
106
            }
107
108
            // Otherwise, encode the character
109 516
            return \rawurlencode($matches[0]);
110 639
        }, $uri);
111
    }
112
}
113