Completed
Push — master ( 1162ff...7d91ca )
by Colin
04:14
created

UrlEncoder::decode()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 14
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 7
nc 1
nop 1
crap 2
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
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
    /**
43
     * @param string $uri
44
     *
45
     * @return string
46
     */
47 552
    public static function unescapeAndEncode($uri)
48
    {
49 552
        $decoded = html_entity_decode($uri);
50
51 552
        return self::encode(self::decode($decoded));
52
    }
53
54
    /**
55
     * Decode a percent-encoded URI
56
     *
57
     * @param string $uri
58
     *
59
     * @return string
60
     */
61 368
    private static function decode($uri)
62
    {
63 184
        return preg_replace_callback('/%([0-9a-f]{2})/iu', function($matches) {
64
            // Convert percent-encoded codes to uppercase
65 15
            $upper = strtoupper($matches[0]);
66
            // Keep excluded characters as-is
67 15
            if (array_key_exists($upper, self::$dontEncode)) {
68 6
                return $upper;
69
            }
70
71
            // Otherwise, return the character for this codepoint
72 12
            return chr(hexdec($matches[1]));
73 552
        }, $uri);
74
    }
75
76
    /**
77
     * Encode a URI, preserving already-encoded and excluded characters
78
     *
79
     * @param string $uri
80
     *
81
     * @return string
82
     */
83
    private static function encode($uri)
84
    {
85 552
        return preg_replace_callback('/(%[0-9a-f]{2})|./iu', function($matches){
86
            // Keep already-encoded characters as-is
87 543
            if (count($matches) > 1) {
88 6
                return $matches[0];
89
            }
90
91
            // Keep excluded characters as-is
92 543
            if (in_array($matches[0], self::$dontEncode)) {
93 477
                return $matches[0];
94
            }
95
96
            // Otherwise, encode the character
97 483
            return rawurlencode($matches[0]);
98 552
        }, $uri);
99
    }
100
}
101