Passed
Push — master ( b083ab...a3db06 )
by Sebastian
03:30
created

URIHighlighter   A

Complexity

Total Complexity 31

Size/Duplication

Total Lines 262
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 31
eloc 119
c 0
b 0
f 0
dl 0
loc 262
rs 9.92

16 Methods

Rating   Name   Duplication   Size   Complexity  
A resolveTag() 0 20 3
A render_port() 0 10 2
A highlight() 0 8 1
A highlight_url() 0 21 2
A render_path() 0 13 2
A render_scheme() 0 12 2
A highlight_email() 0 6 1
A highlight_phone() 0 3 1
A resolveParams() 0 14 2
A __construct() 0 3 1
A render_params() 0 46 5
A render_host() 0 9 2
A render_fragment() 0 10 2
A highlight_fragment() 0 6 1
A render_username() 0 13 2
A getHighlightCSS() 0 13 2
1
<?php
2
/**
3
 * @package Application Utils
4
 * @subpackage URLInfo
5
 * @see \AppUtils\URIHighlighter
6
 */
7
8
declare(strict_types=1);
9
10
namespace AppUtils;
11
12
use AppUtils\URLInfo\URLException;
13
14
/**
15
 * Handles highlighting a previously parsed URL. 
16
 *
17
 * @package Application Utils
18
 * @subpackage URLInfo
19
 * @author Sebastian Mordziol <[email protected]>
20
 */
21
class URIHighlighter
22
{
23
    protected URLInfo $info;
24
    
25
    public function __construct(URLInfo $info)
26
    {
27
        $this->info = $info;
28
    }
29
    
30
    public function highlight() : string
31
    {
32
        $method = 'highlight_'.$this->info->getType();
33
        
34
        return 
35
        '<span class="link">'.
36
            $this->$method().
37
        '</span>';
38
    }
39
    
40
    protected function highlight_email() : string
41
    {
42
        return sprintf(
43
            '<span class="link-scheme scheme-mailto">mailto:</span>'.
44
            '<span class="link-host">%s</span>',
45
            $this->info->getPath()
46
        );
47
    }
48
    
49
    protected function highlight_fragment() : string
50
    {
51
        return sprintf(
52
            '<span class="link-fragment-sign">#</span>'.
53
            '<span class="link-fragment-value">%s</span>',
54
            $this->info->getFragment()
55
        );
56
    }
57
    
58
    protected function highlight_phone() : string
59
    {
60
        return $this->highlight_url();
61
    }
62
    
63
    protected function highlight_url() : string
64
    {
65
        $result = [];
66
        
67
        $parts = array(
68
            'scheme',
69
            'username',
70
            'host',
71
            'port',
72
            'path',
73
            'params',
74
            'fragment'
75
        );
76
        
77
        foreach($parts as $part) 
78
        {
79
            $method = 'render_'.$part;
80
            $result[] = (string)$this->$method();
81
        }
82
        
83
        return implode('', $result);
84
    }
85
    
86
    protected function render_scheme() : string
87
    {
88
        if(!$this->info->hasScheme()) {
89
            return '';
90
        }
91
        
92
        return sprintf(
93
            '<span class="link-scheme scheme-%1$s">'.
94
                '%1$s:'.
95
            '</span>'.
96
            '<span class="link-component double-slashes">//</span>',
97
            $this->info->getScheme()
98
        );
99
    }
100
    
101
    protected function render_username() : string
102
    {
103
        if(!$this->info->hasUsername()) {
104
            return '';
105
        }
106
        
107
        return sprintf(
108
            '<span class="link-credentials">%s</span>'.
109
            '<span class="link-component credentials-separator">:</span>'.
110
            '<span class="link-credentials">%s</span>'.
111
            '<span class="link-component credentials-at">@</span>',
112
            $this->info->getUsername(),
113
            $this->info->getPassword()
114
        );
115
    }
116
    
117
    protected function render_host() : string
118
    {
119
        if(!$this->info->hasHost()) {
120
            return '';
121
        }
122
        
123
        return sprintf(
124
            '<span class="link-host">%s</span><wbr>',
125
            $this->info->getHost()
126
        );
127
    }
128
    
129
    protected function render_port() : string
130
    {
131
        if(!$this->info->hasPort()) {
132
            return '';
133
        }
134
        
135
        return sprintf(
136
            '<span class="link-component port-separator">:</span>'.
137
            '<span class="link-port">%s</span>',
138
            $this->info->getPort()
139
        );
140
    }
141
       
142
    protected function render_path() : string
143
    {
144
        if(!$this->info->hasPath()) {
145
            return '';
146
        }
147
        
148
        $path = str_replace(array(';', '='), array(';<wbr>', '=<wbr>'), $this->info->getPath());
149
        $tokens = explode('/', $path);
150
        $path = implode('<span class="link-component path-separator">/</span><wbr>', $tokens);
151
        
152
        return sprintf(
153
            '<span class="link-path">%s</span><wbr>',
154
            $path
155
        );
156
    }
157
    
158
   /**
159
    * Fetches all parameters in the URL, regardless of 
160
    * whether parameter exclusion is enabled, so they
161
    * can be highlighted is need be.
162
    * 
163
    * @return array<string,string>
164
    */
165
    protected function resolveParams() : array
166
    {
167
        $previous = $this->info->isParamExclusionEnabled();
168
        
169
        if($previous)
170
        {
171
            $this->info->setParamExclusion(false);
172
        }
173
        
174
        $params = $this->info->getParams();
175
        
176
        $this->info->setParamExclusion($previous);
177
        
178
        return $params;
179
    }
180
    
181
    protected function render_params() : string
182
    {
183
        $params = $this->resolveParams();
184
        
185
        if(empty($params)) {
186
            return '';
187
        }
188
        
189
        $tokens = array();
190
        $excluded = array();
191
        
192
        if($this->info->isParamExclusionEnabled())
193
        {
194
            $excluded = $this->info->getExcludedParams();
195
        }
196
        
197
        foreach($params as $param => $value)
198
        {
199
            // If the parameter is numeric, it will automatically
200
            // be an integer, so we need the conversion here.
201
            $param = strval($param);
202
203
            $parts = sprintf(
204
                '<span class="link-param-name">%s</span>'.
205
                '<span class="link-component param-equals">=</span>'.
206
                '<span class="link-param-value">%s</span>'.
207
                '<wbr>',
208
                $param,
209
                str_replace(
210
                    array(':', '.', '-', '_'),
211
                    array(':<wbr>', '.<wbr>', '-<wbr>', '_<wbr>'),
212
                    $value
213
                )
214
            );
215
            
216
            $tag = $this->resolveTag($excluded, $param);
217
            
218
            if(!empty($tag))
219
            {
220
                $tokens[] = sprintf($tag, $parts);
221
            }
222
        }
223
        
224
        return
225
        '<span class="link-component query-sign">?</span>'.
226
        implode('<span class="link-component param-separator">&amp;</span>', $tokens);
227
    }
228
229
    /**
230
     * @param array<string,string> $excluded
231
     * @param string $paramName
232
     * @return string
233
     */
234
    protected function resolveTag(array $excluded, string $paramName) : string
235
    {
236
        // regular, non-excluded parameter
237
        if(!isset($excluded[$paramName]))
238
        {
239
            return '<span class="link-param">%s</span>';
240
        }
241
242
        // highlight excluded parameters is disabled, ignore this parameter
243
        if(!$this->info->isHighlightExcludeEnabled())
244
        {
245
            return '';
246
        }
247
            
248
        $tooltip = $excluded[$paramName];
249
                
250
        return sprintf(
251
            '<span class="link-param excluded-param" title="%s" data-toggle="tooltip">%s</span>',
252
            $tooltip,
253
            '%s'
254
        );
255
    }
256
     
257
    protected function render_fragment() : string
258
    {
259
        if(!$this->info->hasFragment()) {
260
            return '';
261
        }
262
        
263
        return sprintf(
264
            '<span class="link-fragment-sign">#</span>'.
265
            '<span class="link-fragment">%s</span>',
266
            $this->info->getFragment()
267
        );
268
    }
269
    
270
    public static function getHighlightCSS() : string
271
    {
272
        $cssFolder = realpath(__DIR__.'/../../css');
273
        
274
        if($cssFolder === false) {
275
            throw new URLException(
276
                'Cannot find package CSS folder.',
277
                null,
278
                URLInfo::ERROR_CANNOT_FIND_CSS_FOLDER
279
            );
280
        }
281
        
282
        return FileHelper::readContents($cssFolder.'/urlinfo-highlight.css');
283
    }
284
}
285